Re: [PATCH v17 06/26] vfio: do proper teardown on VFIO cleanup
From: David Marchand <hidden>
Date: 2026-09-15 15:26:16
On Thu, 10 Sept 2026 at 14:54, Anatoly Burakov [off-list ref] wrote:
Currently, VFIO cleanup only unregisters multiprocess callback, but does not destroy containers, groups, and user mem maps. Do all of that on VFIO cleanup. In order to distinguish between config that is not initialized vs. config that has been initialized but happens to have fd == 0, move the global VFIO enabled flag out of the config, and add a separate per-config "enabled" flag that can be checked to avoid attempting to clean up configs that were never initialized in the first place. While we're at it, also harden the API against repeated initialization and attempts at using the API without having VFIO initialized.
- At this point of the series, I don't see the need for this change. The default config vfio_enabled should be set to 0 and could serve the same purpose? - Should we reset vfio_enabled in rte_vfio_cleanup()?
quoted hunk ↗ jump to hunk
Signed-off-by: Anatoly Burakov <redacted> --- lib/eal/freebsd/eal.c | 3 +- lib/eal/linux/eal_vfio.c | 151 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 7 deletions(-)diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c index 991ca45064..aa6d4c2e16 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c@@ -846,8 +846,7 @@ int rte_vfio_enable(__rte_unused const char *modname) } RTE_EXPORT_INTERNAL_SYMBOL(rte_vfio_cleanup) -void -rte_vfio_cleanup(void) +void rte_vfio_cleanup(void) { }
Nit: unrelated.
quoted hunk ↗ jump to hunk
diff --git a/lib/eal/linux/eal_vfio.c b/lib/eal/linux/eal_vfio.c index 6c77076bc3..d4173f7a01 100644 --- a/lib/eal/linux/eal_vfio.c +++ b/lib/eal/linux/eal_vfio.c
[snip]
quoted hunk ↗ jump to hunk
@@ -2218,9 +2296,72 @@ rte_vfio_container_dma_unmap(int container_fd, uint64_t vaddr, uint64_t iova, return container_dma_unmap(vfio_cfg, vaddr, iova, len); } +static void +vfio_cleanup_config(struct vfio_config *vfio_cfg) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(vfio_cfg->vfio_groups); i++) { + struct vfio_group *group = &vfio_cfg->vfio_groups[i]; + + if (group->group_num == -1) + continue; + if (group->devices != 0) { + EAL_LOG(ERR, "Cannot cleanup VFIO group %d with %d devices", + group->group_num, group->devices); + return;
Why stop? Should we continue for other groups?
+ }
+ if (group->fd >= 0 && close(group->fd) < 0) {
+ EAL_LOG(ERR, "Cannot close VFIO group %d: %s",
+ group->group_num, strerror(errno));
+ return;
+ }
+
+ group->group_num = -1;
+ group->fd = -1;
+ group->devices = 0;
+ vfio_cfg->vfio_active_groups--;
+ }
+
+ /* if there are still active groups, we cannot cleanup the container */
+ if (vfio_cfg->vfio_active_groups != 0) {
+ EAL_LOG(ERR, "Cannot cleanup VFIO container with %d active groups",
+ vfio_cfg->vfio_active_groups);
+ return;
+ }
+
+ if (vfio_cfg->vfio_container_fd >= 0 &&
+ close(vfio_cfg->vfio_container_fd) < 0) {
+ EAL_LOG(ERR, "Cannot close VFIO container: %s", strerror(errno));
+ return;
+ }
+
+ vfio_cfg->vfio_container_fd = -1;
+ vfio_cfg->enabled = false;
+ vfio_cfg->vfio_iommu_type = NULL;
+
+ vfio_cfg->mem_maps.n_maps = 0;
+ memset(vfio_cfg->mem_maps.maps, 0, sizeof(vfio_cfg->mem_maps.maps));
+}-- David Marchand