1. Device Arguments

1.1. 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:

  1. Multi-layer syntax - Generic syntax for device filtering by bus, class, or driver.

  2. Simplified syntax - Legacy simplified syntax.

1.2. Devargs Syntax

1.2.1. 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:

bus=<busname>,<bus_args>/class=<classname>,<class_args>/driver=<drvname>,<driver_args>

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:

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).

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.

1.2.2. Simplified syntax

In cases where the full syntax is not required, devargs can be used with simplified format that targets specific devices only:

[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:

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.

1.3. 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.

1.3.1. 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:

[vdev:]<driver_name><instance_number>[,arg=val,...]

Examples:

Create a ring-based virtual port:

net_ring0

Create a PCAP virtual device with input file:

net_pcap0,rx_pcap=input.pcap

1.4. Using Devargs in Applications

1.4.1. At EAL Initialization

Devargs can be specified on the command line when starting a DPDK application:

Allow-list (permit specific devices):

./myapp -a 0000:02:00.0 -a 03:00.0,txq_inline=128

Block-list (exclude specific devices):

./myapp -b 04:00.0

Virtual devices:

./myapp --vdev net_ring0 --vdev 'net_pcap0,rx_pcap=input.pcap'

See EAL parameters for complete EAL parameter documentation.

1.4.2. At Runtime (Hotplug)

Devargs are used with hotplug APIs to attach devices dynamically:

#include <rte_dev.h>

/* 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 Device Hotplug for detailed information on runtime device management.

1.5. Parsing Devargs in Drivers

PMD drivers can parse devargs using the kvargs library:

#include <rte_kvargs.h>

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:

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 */
}

1.6. Finding Devices by Devargs

DPDK provides iterator helpers that accept devargs-style filters for device enumeration. Examples:

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)