.. SPDX-License-Identifier: BSD-3-Clause Copyright(c) 2026 Intel Corporation. Device Arguments ================ Introduction ------------ Device arguments (devargs) provide a standardized way to specify and configure devices in DPDK applications. Devargs are used both during EAL initialization (via ``rte_eal_init()`` command-line options) and at runtime (via hotplug API) to identify devices and pass configuration parameters to them. A devargs string can specify identifiers and arguments at multiple levels: Bus identifier and arguments Which bus handles the device (e.g., ``pci``, ``vdev``) and bus-level parameters. Class identifier and arguments Device class (e.g., ``eth``, ``crypto``) and class-level parameters. Driver identifier and arguments The specific driver and its driver-specific parameters. DPDK supports two devargs syntaxes: #. **Multi-layer syntax** - Generic syntax for device filtering by bus, class, or driver. #. **Simplified syntax** - Legacy simplified syntax. Devargs Syntax -------------- Generic Syntax ~~~~~~~~~~~~~~ Generic devargs syntax is meant to cover all use cases supported by devargs infrastructure, such as passing arguments to various layers or matching multiple devices. The basic syntax format is as follows: .. code-block:: none bus=,/class=,/driver=, This allows the user to specify: * ``bus`` layer: bus identifier, as well as bus-level arguments * ``class`` layer: class identifier, as well as class-level arguments * ``driver`` layer: driver identifier, as well as driver-specific parameters .. note:: By default, multi-layer syntax is driver-centric and will match all devices using a particular bus, class, and driver combination. To target a specific device, provide a device-identifying argument to the bus layer. The specific key depends on the bus: for PCI use ``addr=`` (e.g. ``bus=pci,addr=02:00.0``), for most other buses use ``name=`` (e.g. ``bus=vdev,name=net_ring0``). As far as PCI BDFs go, the domain part (``0000:``) can be omitted if it is zero, so ``0000:02:00.0`` and ``02:00.0`` are equivalent. **Example**: .. code-block:: none bus=pci/class=eth/driver=ice,representor=[0-3] The above example will pass ``representor=[0-3]`` devarg to each device matching the provided criteria (PCI bus, Ethernet class, in use by ``ice`` driver). .. code-block:: none bus=pci,addr=02:00.0/driver=ice,representor=[0-3] The above example will pass ``representor=[0-3]`` devarg only to device corresponding to PCI address ``0000:02:00.0``, and only if it is managed by ``ice`` driver. Simplified syntax ~~~~~~~~~~~~~~~~~ In cases where the full syntax is not required, devargs can be used with simplified format that targets specific devices only: .. code-block:: none [bus:]device_identifier[,arg1=val1,arg2=val2,...] Where: * ``bus:`` is an optional prefix specifying the bus name (pci, vdev, auxiliary, etc.) * ``device_identifier`` uniquely identifies the device on its bus * ``arg1=val1,arg2=val2,...`` are optional driver-specific configuration parameters The arguments are provided to the driver, but the driver name itself is inferred from the device and does not need to be specified. **Examples**: .. code-block:: none 0000:02:00.0 # PCI device, no arguments 02:00.0,txq_inline=128 # PCI device with driver arguments pci:0000:02:00.0 # Explicit bus prefix net_ring0 # Virtual device vdev:net_pcap0,rx_pcap=input.pcap # Virtual device with arguments and bus prefix If the bus prefix is omitted, DPDK tries each registered bus in turn to see if it can recognize the device identifier. Virtual Device Arguments ------------------------ Virtual devices (vdevs) are software-based devices that don't correspond to physical hardware. Unlike PCI or other hardware buses where devices are discovered by scanning, virtual devices must be explicitly created by specifying their driver name. Understanding Virtual Device Naming ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A virtual device name consists of: Driver name The vdev driver to use (e.g., ``net_ring``, ``net_pcap``, ``crypto_null``). Instance identifier A numeric suffix to create multiple instances of the same driver. **Format**: .. code-block:: none [vdev:][,arg=val,...] **Examples**: Create a ring-based virtual port: .. code-block:: none net_ring0 Create a PCAP virtual device with input file: .. code-block:: none net_pcap0,rx_pcap=input.pcap Using Devargs in Applications ----------------------------- At EAL Initialization ~~~~~~~~~~~~~~~~~~~~~ Devargs can be specified on the command line when starting a DPDK application: **Allow-list (permit specific devices)**: .. code-block:: console ./myapp -a 0000:02:00.0 -a 03:00.0,txq_inline=128 **Block-list (exclude specific devices)**: .. code-block:: console ./myapp -b 04:00.0 **Virtual devices**: .. code-block:: console ./myapp --vdev net_ring0 --vdev 'net_pcap0,rx_pcap=input.pcap' See :doc:`../linux_gsg/linux_eal_parameters` for complete EAL parameter documentation. At Runtime (Hotplug) ~~~~~~~~~~~~~~~~~~~~ Devargs are used with hotplug APIs to attach devices dynamically: .. code-block:: c #include /* Attach a PCI device */ ret = rte_dev_probe("0000:05:00.0"); if (ret < 0) { /* Handle error */ } /* Attach a virtual device */ ret = rte_dev_probe("net_ring1"); if (ret < 0) { /* Handle error */ } /* Attach with arguments */ ret = rte_dev_probe("05:00.0,txq_inline=256"); if (ret < 0) { /* Handle error */ } See :doc:`device_hotplug` for detailed information on runtime device management. Parsing Devargs in Drivers --------------------------- PMD drivers can parse devargs using the kvargs library: .. code-block:: c #include static int my_driver_parse_devargs(struct rte_devargs *devargs) { struct rte_kvargs *kvlist; const char *valid_args[] = {"arg1", "arg2", NULL}; if (devargs == NULL || devargs->args == NULL) return 0; kvlist = rte_kvargs_parse(devargs->args, valid_args); if (kvlist == NULL) { RTE_LOG(ERR, PMD, "Failed to parse devargs\n"); return -EINVAL; } /* Process each argument */ rte_kvargs_process(kvlist, "arg1", my_arg1_handler, NULL); rte_kvargs_process(kvlist, "arg2", my_arg2_handler, NULL); rte_kvargs_free(kvlist); return 0; } For Ethernet devices, use ``rte_eth_devargs_parse()`` to parse standard Ethernet arguments like representors: .. code-block:: c struct rte_eth_devargs eth_da[RTE_MAX_ETHPORTS]; int n_devargs; n_devargs = rte_eth_devargs_parse(devargs_str, eth_da, RTE_MAX_ETHPORTS); if (n_devargs < 0) { /* Handle error */ } Finding Devices by Devargs -------------------------- DPDK provides iterator helpers that accept devargs-style filters for device enumeration. Examples: .. code-block:: c RTE_DEV_FOREACH(dev, "bus=pci", &it) { /* Handle each PCI device */ } /* Ethernet devices can also be filtered by class */ RTE_ETH_FOREACH_MATCHING_DEV(port_id, "class=eth,mac=00:11:22:33:44:55", &it) { /* Handle each Ethernet device */ } For more information, see: * API documentation: ``rte_devargs_parse()``, ``rte_devargs_layers_parse()`` (in ``rte_devargs.h``) * API documentation: ``rte_eth_devargs_parse()`` (in ``ethdev_driver.h``)