[RFC v2 5/5] eal: configure initial device probing

Robin Jarry rjarry at redhat.com
Thu Feb 26 17:50:24 CET 2026


David Marchand, Feb 26, 2026 at 17:20:
> Some applications use port hotplug as their primary way for using DPDK
> resources.
> Having a systematic device probing is a problem when not all available
> resources will be used by the application, as such applications won't set
> an explicit allow list at startup.
>
> This is the case for OVS on systems with multiple mlx5 devices:
> one device can be used by the kernel while the other(s) are used by DPDK.
> In such a setup, the kernel used device may get reconfigured in
> unexpected ways and trigger issues like the one described by Kevin
> not so long ago in bugzilla 1873.
>
> Add an EAL option so that we can change the default behavior from
> block-listing to allow-listing.
>
> Signed-off-by: David Marchand <david.marchand at redhat.com>
> ---
> Changes since RFC v1:
> - changed approach following Bruce suggestion,

Hey David,

thanks for the patch. The idea looks much nicer than some magic PCI bus
value that disables auto probing.

I have a few cosmetic remarks below:

>
> ---
>  app/test/test_eal_flags.c                 |  9 ++++++++
>  devtools/test-null.sh                     |  2 +-
>  doc/guides/linux_gsg/eal_args.include.rst |  6 ++++++
>  lib/eal/common/eal_common_bus.c           | 25 +++++++++++++++++------
>  lib/eal/common/eal_common_options.c       |  3 +++
>  lib/eal/common/eal_option_list.h          |  1 +
>  lib/eal/common/eal_private.h              |  6 ++++++
>  7 files changed, 45 insertions(+), 7 deletions(-)
>
> diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
> index b3a8d0ae6f..a58d0b9c06 100644
> --- a/app/test/test_eal_flags.c
> +++ b/app/test/test_eal_flags.c
> @@ -1030,6 +1030,10 @@ test_misc_flags(void)
>  	const char * const argv28[] = {prgname, prefix, mp_flag, eal_debug_logs,
>  				       "--log-color=invalid" };
>  
> +	/* Try running with --allow-explicitly */
> +	const char * const argv29[] = {prgname, prefix, mp_flag, eal_debug_logs,
> +				       "--allow-explicitly" };

I am not convinced by the option name. What do you think of:

	--no-autoprobe

That would match the Linux sriov_drivers_autoprobe sysfs.

> +
>  	/* run all tests also applicable to FreeBSD first */
>  
>  	if (launch_proc(argv0) == 0) {
> @@ -1176,6 +1180,11 @@ test_misc_flags(void)
>  			__LINE__);
>  		goto fail;
>  	}
> +	if (launch_proc(argv29) != 0) {
> +		printf("Error (line %d) - process did not run ok with --allow-explicitly parameter\n",
> +			__LINE__);
> +		goto fail;
> +	}
>  
>  	rmdir(hugepath_dir3);
>  	rmdir(hugepath_dir2);
> diff --git a/devtools/test-null.sh b/devtools/test-null.sh
> index 8f21189262..37b8760f60 100755
> --- a/devtools/test-null.sh
> +++ b/devtools/test-null.sh
> @@ -30,7 +30,7 @@ logfile=$build/test-null.log
>  (sleep 1 && echo stop) |
>  # testpmd only needs 20M, make it x2 (default number of cores) for NUMA systems
>  $testpmd -l $corelist --no-huge -m 40 \
> -	$libs -a 0:0.0 --vdev net_null1 --vdev net_null2 $eal_options -- \
> +	$libs --allow-explicitly --vdev net_null1 --vdev net_null2 $eal_options -- \
>  	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia | tee $logfile
>  
>  # we expect two ports and some traffic is received and transmitted
> diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
> index 4a3c4d9b5f..f6e56468b5 100644
> --- a/doc/guides/linux_gsg/eal_args.include.rst
> +++ b/doc/guides/linux_gsg/eal_args.include.rst
> @@ -101,6 +101,12 @@ Lcore-related options
>  Device-related options
>  ~~~~~~~~~~~~~~~~~~~~~~
>  
> +*   ``--allow-explicitly``
> +
> +    By default, EAL probes all devices on every available bus, unless some ``-a``/``-b``/``--vdev``
> +    options are passed.
> +    However, when an application relies on hotplug, it may want to plug each device explicitly.

Can you reword this to make it explicit what the flag does? E.g.:

	Disable automatic probing of non-blocked devices.

> +
>  *   ``-b, --block <[domain:]bus:devid.func>``
>  
>      Skip probing a PCI device to prevent EAL from using it.
> diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
> index fbe20cfe35..9a29c6a062 100644
> --- a/lib/eal/common/eal_common_bus.c
> +++ b/lib/eal/common/eal_common_bus.c
> @@ -15,6 +15,8 @@
>  #include <eal_export.h>
>  #include "eal_private.h"
>  
> +static bool allow_explicitly;
> +
>  static struct rte_bus_list rte_bus_list =
>  	TAILQ_HEAD_INITIALIZER(rte_bus_list);
>  
> @@ -98,6 +100,12 @@ rte_bus_probe(void)
>  	return 0;
>  }
>  
> +void
> +eal_bus_set_allow_explicitly(void)
> +{
> +	allow_explicitly = true;
> +}
> +
>  /* Clean up all devices of all buses */
>  int
>  eal_bus_cleanup(void)
> @@ -231,16 +239,21 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_is_ignored_device)
>  bool
>  rte_bus_is_ignored_device(const struct rte_bus *bus, const struct rte_devargs *devargs)
>  {
> -	switch (bus->conf.scan_mode) {
> -	case RTE_BUS_SCAN_ALLOWLIST:
> +	enum rte_bus_scan_mode scan_mode = bus->conf.scan_mode;
> +
> +	if (scan_mode == RTE_BUS_SCAN_UNDEFINED) {
> +		if (allow_explicitly)
> +			scan_mode = RTE_BUS_SCAN_ALLOWLIST;
> +		else
> +			scan_mode = RTE_BUS_SCAN_BLOCKLIST;
> +	}
> +
> +	if (scan_mode == RTE_BUS_SCAN_ALLOWLIST) {
>  		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
>  			return false;
> -		break;
> -	case RTE_BUS_SCAN_UNDEFINED:
> -	case RTE_BUS_SCAN_BLOCKLIST:
> +	} else {
>  		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
>  			return false;
> -		break;
>  	}
>  	return true;
>  }
> diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
> index aad676a004..3f75f2c436 100644
> --- a/lib/eal/common/eal_common_options.c
> +++ b/lib/eal/common/eal_common_options.c
> @@ -1972,6 +1972,9 @@ eal_parse_args(void)
>  		}
>  	}
>  
> +	if (args.allow_explicitly)
> +		eal_bus_set_allow_explicitly();
> +
>  	/* device -a/-b/-vdev options*/
>  	TAILQ_FOREACH(arg, &args.allow, next)
>  		if (eal_option_device_add(RTE_DEVTYPE_ALLOWED, arg->arg) < 0)
> diff --git a/lib/eal/common/eal_option_list.h b/lib/eal/common/eal_option_list.h
> index abee16340b..4e02766500 100644
> --- a/lib/eal/common/eal_option_list.h
> +++ b/lib/eal/common/eal_option_list.h
> @@ -32,6 +32,7 @@
>   * Format of each entry: long name, short name, help string, struct member name.
>   */
>  /* (Alphabetical) List of common options first */
> +BOOL_ARG("--allow-explicitly", NULL, "Change EAL device probing to consider only allowed devices", allow_explicitly)

Depending on what option name we settle on, could you add a short flag
too? E.g.:

BOOL_ARG("--no-autoprobe", "-N", "Disable automatic probing of non-blocked devices", no_autoprobe)

Or:

BOOL_ARG("--no-autoprobe", "-P", "Disable automatic probing of non-blocked devices", no_autoprobe)

>  LIST_ARG("--allow", "-a", "Add device to allow-list, causing DPDK to only use specified devices", allow)
>  STR_ARG("--base-virtaddr", NULL, "Base virtual address to reserve memory", base_virtaddr)
>  LIST_ARG("--block", "-b", "Add device to block-list, preventing DPDK from using the device", block)
> diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
> index e032dd10c9..0bad3de56c 100644
> --- a/lib/eal/common/eal_private.h
> +++ b/lib/eal/common/eal_private.h
> @@ -469,6 +469,12 @@ int rte_eal_memory_detach(void);
>   */
>  struct rte_bus *rte_bus_find_by_device_name(const char *str);
>  
> +/**
> + * Change behavior of rte_bus_probe() from a block-listing approach
> + * to an allow-listing approach.
> + */
> +void eal_bus_set_allow_explicitly(void);
> +
>  /**
>   * For each device on the buses, call the driver-specific function for
>   * device cleanup.



More information about the dev mailing list