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.

Reply via email to