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 <[email protected]>
> ---
> 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.