Re: [PATCH v10 00/20] Support VFIO cdev API in DPDK

Stephen Hemminger <[email protected]>
Newsgroups org.dpdk.dev
Message-ID <[email protected]>
On Thu,  6 Aug 2026 15:11:00 +0100
Anatoly Burakov <[email protected]> wrote:

> This patchset introduces a major refactor of the VFIO subsystem in DPDK to
> support character device (cdev) interface introduced in Linux kernel, as well as
> make the API more streamlined and useful. The goal is to simplify device
> management, improve compatibility, and clarify API responsibilities.
> 
> The following sections outline the key issues addressed by this patchset and the
> corresponding changes introduced.
> 
> 1. Only group mode is supported
> ===============================
> 
> Since kernel version 4.14.327 (LTS), VFIO supports the new character device
> (cdev)-based way of working with VFIO devices (otherwise known as IOMMUFD). This
> is a device-centric mode and does away with all the complexity regarding groups
> and IOMMU types, delegating it all to the kernel, and exposes a much simpler
> interface to userspace.
> 
> The old group interface is still around, and will need to be kept in DPDK both
> for compatibility reasons, as well as supporting special cases (FSLMC bus, NBL
> driver, no-IOMMU mode etc.), but it is now internal-only and not exposed through
> the API the way it was before.
> 
> To enable this, VFIO is heavily refactored, so that the code can support both
> modes while relying on (mostly) common infrastructure.
> 
> Note that the existing `rte_vfio_device_setup/release` model is fundamentally
> incompatible with cdev mode, because for custom container cases, the expected
> flow is that the user binds the IOMMU group (and thus, implicitly, the device
> itself) to a specific container using `rte_vfio_container_group_bind`, whereas
> this step is not needed for cdev as the device fd is assigned to the container
> straight away.
> 
> Therefore, what we do instead is introduce a new API for container device
> assignment which, semantically, will assign a device to specified container, so
> that when it is mapped using `rte_pci_map_device`, the appropriate container is
> selected. Under the hood though, we essentially transition to getting device fd
> straight away at assign stage, so that by the time the PCI bus attempts to map
> the device, it is already mapped and we just return an fd. There is no
> "unassign" API because `release_device` already performs that function.
> 
> Additionally, a new `rte_vfio_get_mode` API is added for those cases that need
> some introspection into VFIO's internals, with three new modes: group
> (old-style), no-iommu (old-style but without IOMMU), and cdev (the new mode).
> Although no-IOMMU is technically a variant of group mode, the distinction is
> largely irrelevant to the user, as all usages of noiommu checks in our codebase
> are for deciding whether to use IOVA or PA, not anything to do with managing
> groups. The current plan for kernel community is to *not* introduce no-IOMMU
> cdev implementation, and IOMMUFD's own group API compatibility layer also does
> not implement no-IOMMU mode, which is why this will be kept for compatibility
> for these use cases.
> 
> There were other users of VFIO which relied on group API but only for convenience
> purposes; no actual VFIO functionality depended on those API's. Therefore, group
> API's are removed and, where appropriate, replaced with the new API's.
> 
> List of removed API's:
> 
> * `rte_vfio_get_group_fd`
> * `rte_vfio_clear_group`
> * `rte_vfio_container_group_bind` (replaced by container assign API)
> * `rte_vfio_container_group_unbind`
> * `rte_vfio_noiommu_is_enabled` (replaced by new mode API)
> 
> 2. The API responsibilities aren't clear and bleed into each other
> ==================================================================
> 
> Some API's do multiple things at once. In particular:
> 
> * `rte_vfio_get_device_info` will setup the device
> * `rte_vfio_setup_device` will get device info
> 
> These API's have been adjusted to do one thing only.
> 
> v10:
> - Added a patch that renames confusing error labels
> - Fixed compiler warning about unused variable
> 
> v9:
> - Moved erroneous rte_errno-related comments to later in the patchset
> - Moved removal of vDPA group fd API's to their respective patches
> - Fixed typo in errno comments (ENXIO vs ENOXIO)
> - Fixed corruption of group config in secondary process (v8 AI review)
> 
> v8:
> - Rebase
> - Fixed build errors due to variable shadowing
> - Removed duplicate fd check as kernel does not provide a way to distinguish
>   between device fd's
> 
> v7:
> - Rebase
> - Added removal of deprecation notices
> - Fixed implicit numeric comparison in patch 12
> 
> v6:
> - Fixed missing header include in vfio cdev file
> 
> v5:
> - Added back missing uapi patch
> 
> v4:
> - Fixed issues with documenting rte_vfio_mode enum
> - Separated deprecation notices into a separate patchset
> 
> v3:
> - Make API removal cleaner
> - Fix `get_group_num` usages to align with new API
> - Fix issues with function exports
> - Fix issues with `setup_device` returning old-style values in some cases
> 
> v2:
> - Make the entire API internal
> - More aggressive API pruning, complete removal of group API
> - Fixed a bug in group mode where device could not be used
> - Better documentation and deprecation notice patches
> - Moved doc patches to beginning of patchset
> 
> Anatoly Burakov (20):
>   uapi: update to v6.17 and add iommufd.h
>   vfio: make all functions internal
>   bus/pci: rename mismatching error labels
>   vfio: split get device info from setup
>   vfio: add container device assignment API
>   net/nbl: do not use VFIO group bind API
>   net/ntnic: use container device assignment API
>   vdpa/ifc: use container device assignment API
>   vdpa/nfp: use container device assignment API
>   vdpa/sfc: use container device assignment API
>   vdpa/mlx5: remove group-related API
>   vhost: remove group-related API from driver
>   vfio: remove group-based API
>   vfio: cleanup and refactor
>   bus/pci: use the new VFIO mode API
>   bus/fslmc: use the new VFIO mode API
>   net/hinic3: use the new VFIO mode API
>   net/ntnic: use the new VFIO mode API
>   vfio: remove no-IOMMU check API
>   vfio: introduce cdev mode
> 
>  config/arm/meson.build                    |    1 +
>  config/meson.build                        |    1 +
>  doc/guides/prog_guide/vhost_lib.rst       |    4 -
>  doc/guides/rel_notes/deprecation.rst      |   10 -
>  drivers/bus/cdx/cdx_vfio.c                |   25 +-
>  drivers/bus/fslmc/fslmc_bus.c             |   10 +-
>  drivers/bus/fslmc/fslmc_vfio.c            |    6 +-
>  drivers/bus/pci/linux/pci.c               |    2 +-
>  drivers/bus/pci/linux/pci_vfio.c          |   47 +-
>  drivers/bus/platform/platform.c           |    9 +-
>  drivers/crypto/bcmfs/bcmfs_vfio.c         |   14 +-
>  drivers/net/hinic3/base/hinic3_hwdev.c    |    3 +-
>  drivers/net/nbl/nbl_common/nbl_userdev.c  |   21 +-
>  drivers/net/nbl/nbl_include/nbl_include.h |    1 +
>  drivers/net/ntnic/ntnic_ethdev.c          |    2 +-
>  drivers/net/ntnic/ntnic_vfio.c            |   30 +-
>  drivers/vdpa/ifc/ifcvf_vdpa.c             |   34 +-
>  drivers/vdpa/mlx5/mlx5_vdpa.c             |    1 -
>  drivers/vdpa/nfp/nfp_vdpa.c               |   37 +-
>  drivers/vdpa/sfc/sfc_vdpa.c               |   39 +-
>  drivers/vdpa/sfc/sfc_vdpa.h               |    2 -
>  kernel/linux/uapi/linux/iommufd.h         | 1292 +++++++++++
>  kernel/linux/uapi/linux/vduse.h           |    2 +-
>  kernel/linux/uapi/linux/vfio.h            |   12 +-
>  kernel/linux/uapi/version                 |    2 +-
>  lib/eal/freebsd/eal.c                     |   98 +-
>  lib/eal/include/rte_vfio.h                |  387 ++--
>  lib/eal/linux/eal_vfio.c                  | 2444 ++++++++-------------
>  lib/eal/linux/eal_vfio.h                  |  167 +-
>  lib/eal/linux/eal_vfio_cdev.c             |  390 ++++
>  lib/eal/linux/eal_vfio_group.c            |  984 +++++++++
>  lib/eal/linux/eal_vfio_mp_sync.c          |   80 +-
>  lib/eal/linux/meson.build                 |    2 +
>  lib/eal/windows/eal.c                     |    4 +-
>  lib/vhost/vdpa_driver.h                   |    3 -
>  35 files changed, 4263 insertions(+), 1903 deletions(-)
>  create mode 100644 kernel/linux/uapi/linux/iommufd.h
>  create mode 100644 lib/eal/linux/eal_vfio_cdev.c
>  create mode 100644 lib/eal/linux/eal_vfio_group.c
> 

Still lots of open AI review feedback:

Patch 14/20 (vfio: cleanup and refactor)

Error: close(fd 0) on the container error path. CONTAINER_INITIALIZER in
eal_vfio.h sets only the mem_maps lock, so container_fd is 0:

	#define CONTAINER_INITIALIZER \
		((struct container){ \
			.mem_maps = {.lock = RTE_SPINLOCK_RECURSIVE_INITIALIZER,}, \
		})

vfio_container_erase() then does

	if (cfg->container_fd >= 0 && close(cfg->container_fd))

so any container allocated but not yet given an fd closes stdin on
teardown. rte_vfio_container_create() reaches this from three arms
(group open failure, iommufd open failure, default:), and
vfio_select_mode()'s err label reaches it too. The pre-refactor code
initialized every vfio_cfgs[i].vfio_container_fd to -1. Add
.container_fd = -1 to CONTAINER_INITIALIZER, and use that initializer in
vfio_container_erase() rather than (struct container){0}.

Error: double close in vfio_has_supported_extensions(). The
VFIO_CHECK_EXTENSION failure path closes vfio_container_fd and returns
-1, and vfio_group_open_container_fd() closes it again:

	ret = vfio_has_supported_extensions(vfio_container_fd);
	if (ret) {
		EAL_LOG(DEBUG, "No supported IOMMU extensions found!");
		close(vfio_container_fd);
		return -1;
	}

Upstream had the close in the callee on both of its error paths and none
in the caller. The refactor added the caller close but removed only the
n_extensions == 0 close, leaving the ioctl path closing twice. Drop the
close() inside vfio_has_supported_extensions().

Warning: no release notes. The series makes the whole rte_vfio API
internal, removes five public functions, and adds cdev mode. Only
deprecation.rst is touched; release_26_11.rst needs "Removed Items" and
"New Features" entries.

Patch 15/20 (bus/pci: use the new VFIO mode API)

Error: noiommu is never detected. pci_device_iova_mode() runs under
rte_bus_get_iommu_class() at eal.c:689; rte_vfio_enable() does not run
until :775. rte_vfio_get_mode() returns RTE_VFIO_MODE_NONE at that
point, so is_vfio_noiommu_enabled latches to 0 and IOVA VA is chosen on
a noiommu system. rte_vfio_noiommu_is_enabled() read the sysfs knob and
did not depend on VFIO init.

Patch 16/20 (bus/fslmc: use the new VFIO mode API)

Error: fslmc bus scan fails on every system. rte_fslmc_scan() runs from
rte_bus_scan() at eal.c:680, also before rte_vfio_enable(), so

	if (rte_vfio_get_mode() != RTE_VFIO_MODE_GROUP &&
			rte_vfio_get_mode() != RTE_VFIO_MODE_NOIOMMU) {
		ret = -EINVAL;
		goto scan_fail;
	}

always takes the failure branch and no DPAA2 device is ever scanned. The
same ordering issue applies to rte_dpaa2_get_iommu_class() and to
fslmc_vfio_add_group(), which will now always select VFIO_TYPE1_IOMMU.

Warning: the new scan_fail branch logs nothing, unlike every other
failure in that function, so the failure is silent.

Patch 20/20 (vfio: introduce cdev mode)

Error: vfio_cfg.ops is never set in a cdev-mode secondary. The only
assignment is in vfio_cdev_enable(), reached solely from the primary arm
of vfio_select_mode(); the secondary arm calls vfio_sync_mode() and
vfio_cdev_sync_ioas(), neither of which touches ops. Every
rte_vfio_container_dma_map()/dma_unmap() in a cdev secondary therefore
fails in vfio_dma_mem_map() with "VFIO support not initialized". A
container made by rte_vfio_container_create() in a secondary has the
same problem: iommufd opened, IOAS allocated, ops NULL. Set ops in the
secondary cdev path.

Note also that container_dma_map()/container_dma_unmap() dereference
vfio_cfg.ops->partial_unmap with no NULL check; only vfio_dma_mem_map()
guards it.

Patch 3/20 (bus/pci: rename mismatching error labels)

Info: "Specifcally" in the commit body.

Patch 6/20 (net/nbl: do not use VFIO group bind API)

Info: blank line needed between the declaration and the statements in
nbl_open_group_fd().
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.