In case of a single failure, all mapped memory, VFIO resources and device pointers were left untouched. When reaching one init failure during probe, unwind what had been done so far.
Note: the mapping helper was ignoring the memory callback registration failure, so it is kept as is. Signed-off-by: David Marchand <[email protected]> --- Changes since RFC v2: - rebased, --- drivers/bus/fslmc/fslmc_bus.c | 10 ++++-- drivers/bus/fslmc/fslmc_vfio.c | 56 +++++++++++++++++++++++++++++----- drivers/bus/fslmc/fslmc_vfio.h | 1 + 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c index 0600f1afd5..b3ebf41fd7 100644 --- a/drivers/bus/fslmc/fslmc_bus.c +++ b/drivers/bus/fslmc/fslmc_bus.c @@ -423,17 +423,23 @@ rte_fslmc_probe(struct rte_bus *bus) if (ret) { DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret); DPAA2_BUS_ERR("FSLMC VFIO Mapping failed"); - return ret; + goto vfio_close_group; } } ret = fslmc_vfio_process_group(); if (ret) { DPAA2_BUS_ERR("Unable to setup devices %d", ret); - return ret; + goto vfio_dma_unmap; } return rte_bus_generic_probe(bus); + +vfio_dma_unmap: + fslmc_vfio_dmaunmap(); +vfio_close_group: + fslmc_vfio_close_group(); + return ret; } static bool diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c index 10efd98e7b..c0ecf84cc7 100644 --- a/drivers/bus/fslmc/fslmc_vfio.c +++ b/drivers/bus/fslmc/fslmc_vfio.c @@ -1168,6 +1168,27 @@ fslmc_dmamap_seg(const struct rte_memseg_list *msl __rte_unused, return ret; } +static int +fslmc_dmaunmap_seg(const struct rte_memseg_list *msl __rte_unused, + const struct rte_memseg *ms, void *arg) +{ + int *n_segs = arg; + int ret; + + /* if IOVA address is invalid, skip */ + if (ms->iova == RTE_BAD_IOVA) + return 0; + + ret = fslmc_unmap_dma(ms->addr_64, ms->iova, ms->len); + if (ret) + DPAA2_BUS_ERR("Unable to VFIO unmap (addr=%p, len=%zu)", + ms->addr, ms->len); + else + (*n_segs)++; + + return ret; +} + RTE_EXPORT_SYMBOL(rte_fslmc_vfio_mem_dmamap) int rte_fslmc_vfio_mem_dmamap(uint64_t vaddr, uint64_t iova, uint64_t size) @@ -1191,10 +1212,8 @@ fslmc_vfio_dmamap(void) rte_mcfg_mem_read_lock(); ret = rte_memseg_walk(fslmc_dmamap_seg, &i); - if (ret) { - rte_mcfg_mem_read_unlock(); - return ret; - } + if (ret != 0) + goto unmap; ret = rte_mem_event_callback_register("fslmc_memevent_clb", fslmc_memevent_cb, NULL); @@ -1207,12 +1226,33 @@ fslmc_vfio_dmamap(void) DPAA2_BUS_DEBUG("Total %d segments found.", i); - /* Existing segments have been mapped and memory callback for hotplug - * has been installed. - */ + /* Ignore callback handler registration failure */ + ret = 0; + +unmap: + if (ret != 0) { + i = 0; + rte_memseg_walk(fslmc_dmaunmap_seg, &i); + } + rte_mcfg_mem_read_unlock(); - return 0; + return ret; +} + +int +fslmc_vfio_dmaunmap(void) +{ + int i = 0, ret; + + rte_mcfg_mem_read_lock(); + + rte_mem_event_callback_unregister("fslmc_memevent_clb", NULL); + ret = rte_memseg_walk(fslmc_dmaunmap_seg, &i); + + rte_mcfg_mem_read_unlock(); + + return ret; } static int diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h index c995fd67b8..57fe7038de 100644 --- a/drivers/bus/fslmc/fslmc_vfio.h +++ b/drivers/bus/fslmc/fslmc_vfio.h @@ -60,4 +60,5 @@ int fslmc_vfio_close_group(void); char *fslmc_get_container(void); int fslmc_get_container_group(const char *group_name, int *gropuid); int fslmc_vfio_dmamap(void); +int fslmc_vfio_dmaunmap(void); #endif /* _FSLMC_VFIO_H_ */ -- 2.54.0

