public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
* [RFC 1/2] devtools: check packet forwarding in null test
@ 2026-02-25 11:29 David Marchand
  2026-02-25 11:29 ` [RFC 2/2] eal: configure initial device probing David Marchand
                   ` (2 more replies)
  0 siblings, 3 replies; 40+ messages in thread
From: David Marchand @ 2026-02-25 11:29 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko

Add some simple checks that testpmd was indeed polling two ports, and
some packets got through it.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 devtools/test-null.sh | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/devtools/test-null.sh b/devtools/test-null.sh
index e3ac168ce3..8f21189262 100755
--- a/devtools/test-null.sh
+++ b/devtools/test-null.sh
@@ -26,8 +26,14 @@ else
 	libs=
 fi
 
+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 -- \
-	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia
+	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia | tee $logfile
+
+# we expect two ports and some traffic is received and transmitted
+grep -q 'io packet forwarding - ports=2 -' $build/test-null.log
+grep 'RX-packets: ' $logfile | tail -1 | grep -q 'RX-packets:[[:space:]]*[^0[:space:]]'
+grep 'TX-packets: ' $logfile | tail -1 | grep -q 'TX-packets:[[:space:]]*[^0[:space:]]'
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC 2/2] eal: configure initial device probing
  2026-02-25 11:29 [RFC 1/2] devtools: check packet forwarding in null test David Marchand
@ 2026-02-25 11:29 ` David Marchand
  2026-02-25 12:09   ` Bruce Richardson
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
  2 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-02-25 11:29 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko, Bruce Richardson,
	Dmitry Kozlyuk

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 to disable device probing, allowing to select per bus.

Note: the current implementation does not take combinations of the new
option with -a/-b.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 app/test/test.c                           |  1 +
 app/test/test_eal_flags.c                 | 31 ++++++++++++++
 devtools/test-null.sh                     |  2 +-
 doc/guides/linux_gsg/eal_args.include.rst |  7 ++++
 lib/eal/common/eal_common_bus.c           | 50 ++++++++++++++++++++---
 lib/eal/common/eal_common_options.c       | 14 +++++++
 lib/eal/common/eal_internal_cfg.h         |  2 +
 lib/eal/common/eal_option_list.h          |  1 +
 lib/eal/common/eal_private.h              | 13 ++++++
 lib/eal/freebsd/eal.c                     |  3 +-
 lib/eal/linux/eal.c                       |  3 +-
 lib/eal/windows/eal.c                     |  2 +-
 12 files changed, 118 insertions(+), 11 deletions(-)

diff --git a/app/test/test.c b/app/test/test.c
index 58ef52f312..296c5a8472 100644
--- a/app/test/test.c
+++ b/app/test/test.c
@@ -72,6 +72,7 @@ do_recursive_call(void)
 			{ "test_main_lcore_flag", no_action },
 			{ "test_invalid_n_flag", no_action },
 			{ "test_no_hpet_flag", no_action },
+			{ "test_no_probe_flag", no_action },
 			{ "test_allow_flag", no_action },
 			{ "test_invalid_b_flag", no_action },
 			{ "test_invalid_vdev_flag", no_action },
diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index b3a8d0ae6f..b5291a5123 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -46,6 +46,13 @@ test_no_huge_flag(void)
 	return TEST_SKIPPED;
 }
 
+static int
+test_no_probe_flag(void)
+{
+	printf("no_probe_flag not supported on Windows, skipping test\n");
+	return TEST_SKIPPED;
+}
+
 static int
 test_allow_flag(void)
 {
@@ -302,6 +309,29 @@ get_number_of_sockets(void)
 }
 #endif /* RTE_EXEC_ENV_LINUX */
 
+static int
+test_no_probe_flag(void)
+{
+	const char *prefix = file_prefix_arg();
+	if (prefix == NULL)
+		return -1;
+
+	const char *wlvalid[][4] = {
+		{prgname, prefix, mp_flag, "--no-probe" },
+		{prgname, prefix, mp_flag, "--no-probe=pci" },
+	};
+
+	for (unsigned int i = 0; i < RTE_DIM(wlvalid); i++) {
+		if (launch_proc(wlvalid[i]) != 0) {
+			printf("Error (line %d) - process did not run with valid no probe parameter\n",
+				__LINE__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * Test that the app doesn't run with invalid allow option.
  * Final tests ensures it does run with valid options as sanity check (one
@@ -1678,6 +1708,7 @@ REGISTER_FAST_TEST(eal_flags_main_opt_autotest, NOHUGE_SKIP, ASAN_SKIP, test_mai
 REGISTER_FAST_TEST(eal_flags_n_opt_autotest, NOHUGE_SKIP, ASAN_SKIP, test_invalid_n_flag);
 REGISTER_FAST_TEST(eal_flags_hpet_autotest, NOHUGE_SKIP, ASAN_SKIP, test_no_hpet_flag);
 REGISTER_FAST_TEST(eal_flags_no_huge_autotest, NOHUGE_SKIP, ASAN_SKIP, test_no_huge_flag);
+REGISTER_FAST_TEST(eal_flags_no_probe_autotest, NOHUGE_SKIP, ASAN_SKIP, test_no_probe_flag);
 REGISTER_FAST_TEST(eal_flags_a_opt_autotest, NOHUGE_SKIP, ASAN_SKIP, test_allow_flag);
 REGISTER_FAST_TEST(eal_flags_b_opt_autotest, NOHUGE_SKIP, ASAN_SKIP, test_invalid_b_flag);
 REGISTER_FAST_TEST(eal_flags_vdev_opt_autotest, NOHUGE_SKIP, ASAN_SKIP, test_invalid_vdev_flag);
diff --git a/devtools/test-null.sh b/devtools/test-null.sh
index 8f21189262..617ba78bbf 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 --no-probe=pci --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..8007b72c15 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -136,6 +136,13 @@ Device-related options
 
     Disable PCI bus.
 
+*   ``--no-probe[=bus list]``
+
+    Disable device probing as part of EAL init. Disabling affects either all buses
+    when no value is passed, or the list of buses. This is especially useful when
+    the DPDK application relies on resources hotplug and has no idea of which
+    device will be used at the time rte_eal_init() is called.
+
 Multiprocessing-related options
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 0a2311a342..315bb99dd8 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -3,6 +3,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/queue.h>
 
@@ -67,15 +68,44 @@ rte_bus_scan(void)
 	return 0;
 }
 
-/* Probe all devices of all buses */
-RTE_EXPORT_SYMBOL(rte_bus_probe)
 int
-rte_bus_probe(void)
+eal_bus_probe(const char *excluded)
 {
-	int ret;
 	struct rte_bus *bus, *vbus = NULL;
+	char *filter = NULL;
+	int ret = 0;
+
+	if (excluded != NULL) {
+		if (!strcmp(excluded, "all")) {
+			EAL_LOG(DEBUG, "Skipped probing all buses");
+			return 0;
+		}
+
+		if (asprintf(&filter, ",%s,", excluded) == -1) {
+			EAL_LOG(ERR, "Could not allocate memory for filtering buses.");
+			return -1;
+		}
+	}
 
 	TAILQ_FOREACH(bus, &rte_bus_list, next) {
+		if (filter != NULL) {
+			char *pattern;
+			bool skip;
+
+			if (asprintf(&pattern, ",%s,", rte_bus_name(bus)) == -1) {
+				EAL_LOG(ERR, "Could not allocate memory for filtering buses.");
+				ret = -1;
+				goto out;
+			}
+			skip = strstr(filter, pattern) != NULL;
+			free(pattern);
+			if (skip) {
+				EAL_LOG(DEBUG, "Skipped probing bus %s", rte_bus_name(bus));
+				continue;
+			}
+			EAL_LOG(DEBUG, "Will probe bus %s", rte_bus_name(bus));
+		}
+
 		if (!strcmp(rte_bus_name(bus), "vdev")) {
 			vbus = bus;
 			continue;
@@ -94,7 +124,17 @@ rte_bus_probe(void)
 				rte_bus_name(vbus));
 	}
 
-	return 0;
+out:
+	free(filter);
+	return ret;
+}
+
+/* Probe all devices of all buses */
+RTE_EXPORT_SYMBOL(rte_bus_probe)
+int
+rte_bus_probe(void)
+{
+	return eal_bus_probe(NULL);
 }
 
 /* Clean up all devices of all buses */
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index aad676a004..a37c245053 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -518,6 +518,8 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
 	memset(internal_cfg->vfio_vf_token, 0,
 			sizeof(internal_cfg->vfio_vf_token));
 
+	internal_cfg->no_probe = NULL;
+
 #ifdef RTE_LIBEAL_USE_HPET
 	internal_cfg->no_hpet = 0;
 #else
@@ -2206,6 +2208,17 @@ eal_parse_args(void)
 	}
 #endif
 
+	if (args.no_probe != NULL) {
+		if (args.no_probe == (void *)1)
+			int_cfg->no_probe = strdup("all");
+		else
+			int_cfg->no_probe = strdup(args.no_probe);
+		if (int_cfg->no_probe == NULL) {
+			EAL_LOG(ERR, "failed to allocate memory for no probe parameter");
+			return -1;
+		}
+	}
+
 	/* simple flag settings
 	 * Only set these to 1, as we don't want to set them to 0 in case
 	 * other options above have already set them.
@@ -2336,6 +2349,7 @@ eal_cleanup_config(struct internal_config *internal_cfg)
 {
 	free(internal_cfg->hugefile_prefix);
 	free(internal_cfg->hugepage_dir);
+	free(internal_cfg->no_probe);
 	free(internal_cfg->user_mbuf_pool_ops_name);
 
 	return 0;
diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h
index 95d327a613..a5fbce36cf 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -57,6 +57,8 @@ struct internal_config {
 	volatile unsigned force_nrank;    /**< force number of ranks */
 	volatile unsigned no_hugetlbfs;   /**< true to disable hugetlbfs */
 	struct hugepage_file_discipline hugepage_file;
+	char *no_probe;
+	/**< a list of (or all) buses to exclude when probing devices at init */
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
diff --git a/lib/eal/common/eal_option_list.h b/lib/eal/common/eal_option_list.h
index abee16340b..487fa191bb 100644
--- a/lib/eal/common/eal_option_list.h
+++ b/lib/eal/common/eal_option_list.h
@@ -51,6 +51,7 @@ STR_ARG("--mbuf-pool-ops-name", NULL, "User defined mbuf default pool ops name",
 STR_ARG("--memory-channels", "-n", "Number of memory channels per socket", memory_channels)
 STR_ARG("--memory-ranks", "-r", "Force number of memory ranks (don't detect)", memory_ranks)
 STR_ARG("--memory-size", "-m", "Total size of memory to allocate initially", memory_size)
+OPT_STR_ARG("--no-probe", NULL, "Disable device probing at init (for all or some buses)", no_probe)
 BOOL_ARG("--no-hpet", NULL, "Disable HPET timer", no_hpet)
 BOOL_ARG("--no-huge", NULL, "Disable hugetlbfs support", no_huge)
 BOOL_ARG("--no-pci", NULL, "Disable all PCI devices", no_pci)
diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
index e032dd10c9..51cc3c5409 100644
--- a/lib/eal/common/eal_private.h
+++ b/lib/eal/common/eal_private.h
@@ -469,6 +469,19 @@ int rte_eal_memory_detach(void);
  */
 struct rte_bus *rte_bus_find_by_device_name(const char *str);
 
+/**
+ * Call all buses probe() function except those present in the
+ * excluded string.
+ *
+ * @param excluded
+ *   A list of bus to exclude separated by ,. A "all" string
+ *   is a special case that results in skipping all buses.
+ * @return
+ *   0 on success;
+ *   (<0) on failure.
+ */
+int eal_bus_probe(const char *excluded);
+
 /**
  * For each device on the buses, call the driver-specific function for
  * device cleanup.
diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c
index 60f5e676a8..f3b4f7485b 100644
--- a/lib/eal/freebsd/eal.c
+++ b/lib/eal/freebsd/eal.c
@@ -717,8 +717,7 @@ rte_eal_init(int argc, char **argv)
 		goto err_out;
 	}
 
-	/* Probe all the buses and devices/drivers on them */
-	if (rte_bus_probe()) {
+	if (eal_bus_probe(internal_conf->no_probe) < 0) {
 		rte_eal_init_alert("Cannot probe devices");
 		rte_errno = ENOTSUP;
 		goto err_out;
diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c
index d848de03d8..c81930987a 100644
--- a/lib/eal/linux/eal.c
+++ b/lib/eal/linux/eal.c
@@ -890,8 +890,7 @@ rte_eal_init(int argc, char **argv)
 		goto err_out;
 	}
 
-	/* Probe all the buses and devices/drivers on them */
-	if (rte_bus_probe()) {
+	if (eal_bus_probe(internal_conf->no_probe) < 0) {
 		rte_eal_init_alert("Cannot probe devices");
 		rte_errno = ENOTSUP;
 		goto err_out;
diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c
index f06375a624..0cb5c090bf 100644
--- a/lib/eal/windows/eal.c
+++ b/lib/eal/windows/eal.c
@@ -398,7 +398,7 @@ rte_eal_init(int argc, char **argv)
 		goto err_out;
 	}
 
-	if (rte_bus_probe()) {
+	if (eal_bus_probe(internal_conf->no_probe) < 0) {
 		rte_eal_init_alert("Cannot probe devices");
 		rte_errno = ENOTSUP;
 		goto err_out;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [RFC 2/2] eal: configure initial device probing
  2026-02-25 11:29 ` [RFC 2/2] eal: configure initial device probing David Marchand
@ 2026-02-25 12:09   ` Bruce Richardson
  2026-02-25 17:53     ` David Marchand
  0 siblings, 1 reply; 40+ messages in thread
From: Bruce Richardson @ 2026-02-25 12:09 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Thomas Monjalon, Andrew Rybchenko, Dmitry Kozlyuk

On Wed, Feb 25, 2026 at 12:29:21PM +0100, David Marchand wrote:
> 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 to disable device probing, allowing to select per bus.
> 
> Note: the current implementation does not take combinations of the new
> option with -a/-b.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Wondering about this problem and fix options. Rather than a new flag for
no-probe, would an alternative flag to switch the default mode from
block-listing to allow-listing work? 

Right now, by default, EAL probes all buses and tries to take all
non-blocklisted devices. We could add a flag to switch that so that we
allow-list by default, which I think should have the same effect as this if
no -a flags are passed. We already have support for managing -a and -b flag
interactions, which should make interacting with the new flag easier.

WDYT?
/Bruce

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 2/2] eal: configure initial device probing
  2026-02-25 12:09   ` Bruce Richardson
@ 2026-02-25 17:53     ` David Marchand
  0 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-02-25 17:53 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, Thomas Monjalon, Andrew Rybchenko, Dmitry Kozlyuk

On Wed, 25 Feb 2026 at 13:09, Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Wed, Feb 25, 2026 at 12:29:21PM +0100, David Marchand wrote:
> > 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 to disable device probing, allowing to select per bus.
> >
> > Note: the current implementation does not take combinations of the new
> > option with -a/-b.
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
> Wondering about this problem and fix options. Rather than a new flag for
> no-probe, would an alternative flag to switch the default mode from
> block-listing to allow-listing work?
>
> Right now, by default, EAL probes all buses and tries to take all
> non-blocklisted devices. We could add a flag to switch that so that we
> allow-list by default, which I think should have the same effect as this if
> no -a flags are passed. We already have support for managing -a and -b flag
> interactions, which should make interacting with the new flag easier.

I like the idea. The devil is in the details though and I'll have to
look carefully at all bus probe() functions.
I'll try to implement as a RFC v2.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [RFC v2 0/5] Rework device probing
  2026-02-25 11:29 [RFC 1/2] devtools: check packet forwarding in null test David Marchand
  2026-02-25 11:29 ` [RFC 2/2] eal: configure initial device probing David Marchand
@ 2026-02-26 16:20 ` David Marchand
  2026-02-26 16:20   ` [RFC v2 1/5] devtools: check packet forwarding in null test David Marchand
                     ` (4 more replies)
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
  2 siblings, 5 replies; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev

Applications relying on device hotplug don't work well with the default
probing of all available resources.
This series proposes to change this behavior via a new EAL option.


-- 
David Marchand

Changes since RFC v1:
- reviewed bus probe() and cleaned up NXP drivers,
- changed approach following Bruce comment,

David Marchand (5):
  devtools: check packet forwarding in null test
  bus/fslmc: fix bus cleanup
  drivers/bus: require probe function for NXP drivers
  bus: factorize device selection
  eal: configure initial device probing

 app/test/test_eal_flags.c                 |  9 +++++++
 devtools/test-null.sh                     | 10 +++++--
 doc/guides/linux_gsg/eal_args.include.rst |  6 +++++
 drivers/bus/auxiliary/auxiliary_common.c  | 15 +----------
 drivers/bus/cdx/cdx.c                     | 21 +--------------
 drivers/bus/dpaa/dpaa_bus.c               | 26 ++++++------------
 drivers/bus/fslmc/fslmc_bus.c             | 29 ++++++--------------
 drivers/bus/fslmc/fslmc_vfio.c            | 22 +++++-----------
 drivers/bus/pci/pci_common.c              | 15 +----------
 drivers/bus/platform/platform.c           | 28 ++------------------
 drivers/bus/uacce/uacce.c                 | 22 +---------------
 drivers/bus/vmbus/vmbus_common.c          | 21 +--------------
 drivers/dma/idxd/idxd_bus.c               | 32 +++++++++--------------
 lib/eal/common/eal_common_bus.c           | 31 ++++++++++++++++++++++
 lib/eal/common/eal_common_options.c       |  3 +++
 lib/eal/common/eal_option_list.h          |  1 +
 lib/eal/common/eal_private.h              |  6 +++++
 lib/eal/include/bus_driver.h              |  7 +++++
 18 files changed, 112 insertions(+), 192 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [RFC v2 1/5] devtools: check packet forwarding in null test
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
@ 2026-02-26 16:20   ` David Marchand
  2026-02-26 16:35     ` Bruce Richardson
  2026-02-26 16:20   ` [RFC v2 2/5] bus/fslmc: fix bus cleanup David Marchand
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko

Add some simple checks that testpmd was indeed polling two ports, and
some packets got through it.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 devtools/test-null.sh | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/devtools/test-null.sh b/devtools/test-null.sh
index e3ac168ce3..8f21189262 100755
--- a/devtools/test-null.sh
+++ b/devtools/test-null.sh
@@ -26,8 +26,14 @@ else
 	libs=
 fi
 
+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 -- \
-	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia
+	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia | tee $logfile
+
+# we expect two ports and some traffic is received and transmitted
+grep -q 'io packet forwarding - ports=2 -' $build/test-null.log
+grep 'RX-packets: ' $logfile | tail -1 | grep -q 'RX-packets:[[:space:]]*[^0[:space:]]'
+grep 'TX-packets: ' $logfile | tail -1 | grep -q 'TX-packets:[[:space:]]*[^0[:space:]]'
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v2 2/5] bus/fslmc: fix bus cleanup
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
  2026-02-26 16:20   ` [RFC v2 1/5] devtools: check packet forwarding in null test David Marchand
@ 2026-02-26 16:20   ` David Marchand
  2026-02-26 16:20   ` [RFC v2 3/5] drivers/bus: require probe function for NXP drivers David Marchand
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev; +Cc: stable, Hemant Agrawal, Sachin Saxena, Rohit Raj

The close operation was never closing probed devices.
Taking a step back, reevaluating the devargs makes no sense during the
close step, as a probed device must have passed the allow/block list
evaluation earlier.

Since the device contains a reference to the driver that probed it,
simply call this driver remove op.

Fixes: 274fd921ff7f ("bus/fslmc: support close operation")
Cc: stable@dpdk.org

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/fslmc/fslmc_vfio.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 550d4e0e8d..481bad196b 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -1393,7 +1393,7 @@ fslmc_close_iodevices(struct rte_dpaa2_device *dev,
 {
 	struct rte_dpaa2_object *object = NULL;
 	struct rte_dpaa2_driver *drv;
-	int ret, probe_all;
+	int ret;
 
 	switch (dev->dev_type) {
 	case DPAA2_IO:
@@ -1411,21 +1411,11 @@ fslmc_close_iodevices(struct rte_dpaa2_device *dev,
 	case DPAA2_ETH:
 	case DPAA2_CRYPTO:
 	case DPAA2_QDMA:
-		probe_all = rte_fslmc_bus.bus.conf.scan_mode !=
-			    RTE_BUS_SCAN_ALLOWLIST;
-		TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
-			if (drv->drv_type != dev->dev_type)
-				continue;
-			if (rte_dev_is_probed(&dev->device))
-				continue;
-			if (probe_all ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy ==
-			     RTE_DEV_ALLOWED)) {
-				ret = drv->remove(dev);
-				if (ret)
-					DPAA2_BUS_ERR("Unable to remove");
-			}
+		drv = dev->driver;
+		if (drv && drv->remove) {
+			ret = drv->remove(dev);
+			if (ret)
+				DPAA2_BUS_ERR("Unable to remove");
 		}
 		break;
 	default:
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v2 3/5] drivers/bus: require probe function for NXP drivers
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
  2026-02-26 16:20   ` [RFC v2 1/5] devtools: check packet forwarding in null test David Marchand
  2026-02-26 16:20   ` [RFC v2 2/5] bus/fslmc: fix bus cleanup David Marchand
@ 2026-02-26 16:20   ` David Marchand
  2026-02-26 16:24     ` Bruce Richardson
  2026-02-26 16:20   ` [RFC v2 4/5] bus: factorize device selection David Marchand
  2026-02-26 16:20   ` [RFC v2 5/5] eal: configure initial device probing David Marchand
  4 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev; +Cc: Hemant Agrawal, Sachin Saxena

Rather than silently ignore an invalid driver, enforce every registered
driver has a probe callback.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/dpaa/dpaa_bus.c   | 6 +++---
 drivers/bus/fslmc/fslmc_bus.c | 7 +------
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index d9830b68ca..5e0f32bfe8 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -614,6 +614,7 @@ void
 rte_dpaa_driver_register(struct rte_dpaa_driver *driver)
 {
 	RTE_VERIFY(driver);
+	RTE_VERIFY(driver->probe != NULL);
 
 	BUS_INIT_FUNC_TRACE();
 
@@ -808,9 +809,8 @@ rte_dpaa_bus_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (!drv->probe ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy == RTE_DEV_BLOCKED))
+			if (dev->device.devargs &&
+			    dev->device.devargs->policy == RTE_DEV_BLOCKED)
 				continue;
 
 			if (probe_all ||
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index abdb0ad50d..ac9fb7a08c 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -465,9 +465,6 @@ rte_fslmc_probe(void)
 			if (ret)
 				continue;
 
-			if (!drv->probe)
-				continue;
-
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
@@ -534,6 +531,7 @@ void
 rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
 {
 	RTE_VERIFY(driver);
+	RTE_VERIFY(driver->probe != NULL);
 
 	TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
 }
@@ -601,9 +599,6 @@ fslmc_bus_plug(struct rte_device *rte_dev)
 		if (ret)
 			continue;
 
-		if (!drv->probe)
-			continue;
-
 		if (rte_dev_is_probed(&dev->device))
 			continue;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v2 4/5] bus: factorize device selection
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
                     ` (2 preceding siblings ...)
  2026-02-26 16:20   ` [RFC v2 3/5] drivers/bus: require probe function for NXP drivers David Marchand
@ 2026-02-26 16:20   ` David Marchand
  2026-02-26 16:31     ` Bruce Richardson
  2026-02-26 16:20   ` [RFC v2 5/5] eal: configure initial device probing David Marchand
  4 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev
  Cc: Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Bruce Richardson, Kevin Laatz

All buses (thankfully) implement the same logic when it comes to
selecting the devices to probe based on -a/-b options.
As we want to adjust how devices are selected, provide a common helper
in EAL and use it in the buses.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/auxiliary/auxiliary_common.c | 15 +----------
 drivers/bus/cdx/cdx.c                    | 21 +---------------
 drivers/bus/dpaa/dpaa_bus.c              | 24 ++++++------------
 drivers/bus/fslmc/fslmc_bus.c            | 22 ++++++----------
 drivers/bus/pci/pci_common.c             | 15 +----------
 drivers/bus/platform/platform.c          | 28 ++-------------------
 drivers/bus/uacce/uacce.c                | 22 +---------------
 drivers/bus/vmbus/vmbus_common.c         | 21 +---------------
 drivers/dma/idxd/idxd_bus.c              | 32 +++++++++---------------
 lib/eal/common/eal_common_bus.c          | 18 +++++++++++++
 lib/eal/include/bus_driver.h             |  7 ++++++
 11 files changed, 58 insertions(+), 167 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index ac766e283e..5baf76441a 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -399,20 +399,7 @@ auxiliary_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
 bool
 auxiliary_is_ignored_device(const char *name)
 {
-	struct rte_devargs *devargs = auxiliary_devargs_lookup(name);
-
-	switch (auxiliary_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
+	return rte_bus_is_ignored_device(&auxiliary_bus.bus, auxiliary_devargs_lookup(name));
 }
 
 static enum rte_iova_mode
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index 729d54337c..ce0da41b82 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -164,25 +164,6 @@ cdx_devargs_lookup(const char *dev_name)
 	return NULL;
 }
 
-static bool
-cdx_ignore_device(const char *dev_name)
-{
-	struct rte_devargs *devargs = cdx_devargs_lookup(dev_name);
-
-	switch (rte_cdx_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 /*
  * Scan one cdx sysfs entry, and fill the devices list from it.
  * It checks if the CDX device is bound to vfio-cdx driver. In case
@@ -282,7 +263,7 @@ cdx_scan(void)
 		if (e->d_name[0] == '.')
 			continue;
 
-		if (cdx_ignore_device(e->d_name))
+		if (rte_bus_is_ignored_device(&rte_cdx_bus.bus, cdx_devargs_lookup(e->d_name)))
 			continue;
 
 		snprintf(dirname, sizeof(dirname), "%s/%s",
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 5e0f32bfe8..bc1dbf3592 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -717,7 +717,6 @@ rte_dpaa_bus_probe(void)
 	struct rte_dpaa_driver *drv;
 	FILE *svr_file = NULL;
 	uint32_t svr_ver;
-	int probe_all = rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST;
 	static int process_once;
 	char *penv;
 
@@ -725,9 +724,6 @@ rte_dpaa_bus_probe(void)
 	if (!rte_dpaa_bus.detected)
 		return 0;
 
-	if (rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST)
-		probe_all = true;
-
 	svr_file = fopen(DPAA_SOC_ID_FILE, "r");
 	if (svr_file) {
 		if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
@@ -809,21 +805,15 @@ rte_dpaa_bus_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_BLOCKED)
+			if (rte_bus_is_ignored_device(&rte_dpaa_bus.bus, dev->device.devargs))
 				continue;
 
-			if (probe_all ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
-				ret = drv->probe(drv, dev);
-				if (ret) {
-					DPAA_BUS_ERR("unable to probe:%s",
-						     dev->name);
-				} else {
-					dev->driver = drv;
-					dev->device.driver = &drv->driver;
-				}
+			ret = drv->probe(drv, dev);
+			if (ret) {
+				DPAA_BUS_ERR("unable to probe: %s", dev->name);
+			} else {
+				dev->driver = drv;
+				dev->device.driver = &drv->driver;
 			}
 			break;
 		}
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index ac9fb7a08c..27ef84659a 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -410,7 +410,6 @@ static int
 rte_fslmc_probe(void)
 {
 	int ret = 0;
-	int probe_all;
 
 	struct rte_dpaa2_device *dev;
 	struct rte_dpaa2_driver *drv;
@@ -457,8 +456,6 @@ rte_fslmc_probe(void)
 		return 0;
 	}
 
-	probe_all = rte_fslmc_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST;
-
 	TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
 		TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
 			ret = rte_fslmc_match(drv, dev);
@@ -468,23 +465,18 @@ rte_fslmc_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+			if (rte_bus_is_ignored_device(&rte_fslmc_bus.bus, dev->device.devargs)) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blocked, skipping",
 					      dev->device.name);
 				continue;
 			}
 
-			if (probe_all ||
-			   (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
-				ret = drv->probe(drv, dev);
-				if (ret) {
-					DPAA2_BUS_ERR("Unable to probe");
-				} else {
-					dev->driver = drv;
-					dev->device.driver = &drv->driver;
-				}
+			ret = drv->probe(drv, dev);
+			if (ret) {
+				DPAA2_BUS_ERR("Unable to probe");
+			} else {
+				dev->driver = drv;
+				dev->device.driver = &drv->driver;
 			}
 			break;
 		}
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index bf5df3d94e..c5cc9db9cf 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -721,20 +721,7 @@ pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 bool
 rte_pci_ignore_device(const struct rte_pci_addr *pci_addr)
 {
-	struct rte_devargs *devargs = pci_devargs_lookup(pci_addr);
-
-	switch (rte_pci_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
+	return rte_bus_is_ignored_device(&rte_pci_bus.bus, pci_devargs_lookup(pci_addr));
 }
 
 enum rte_iova_mode
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index f6673cf181..21f8240e28 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -56,30 +56,6 @@ dev_devargs(const char *dev_name)
 	return NULL;
 }
 
-static bool
-dev_allowed(const char *dev_name)
-{
-	struct rte_devargs *devargs;
-
-	devargs = dev_devargs(dev_name);
-	if (devargs == NULL)
-		return true;
-
-	switch (platform_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs->policy == RTE_DEV_ALLOWED)
-			return true;
-		break;
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs->policy == RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-
-	return true;
-}
-
 static int
 dev_add(const char *dev_name)
 {
@@ -173,7 +149,7 @@ platform_bus_scan(void)
 		if (dev_name[0] == '.')
 			continue;
 
-		if (!dev_allowed(dev_name))
+		if (rte_bus_is_ignored_device(&platform_bus.bus, dev_devargs(dev_name)))
 			continue;
 
 		if (!dev_is_bound_vfio_platform(dev_name))
@@ -497,7 +473,7 @@ platform_bus_plug(struct rte_device *dev)
 {
 	struct rte_platform_device *pdev;
 
-	if (!dev_allowed(dev->name))
+	if (rte_bus_is_ignored_device(&platform_bus.bus, dev->devargs))
 		return -EPERM;
 
 	if (!dev_is_bound_vfio_platform(dev->name))
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 79f990c54c..bf04e22057 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -84,26 +84,6 @@ uacce_devargs_lookup(const char *dev_name)
 	return NULL;
 }
 
-static bool
-uacce_ignore_device(const char *dev_name)
-{
-	struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
-
-	switch (uacce_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-
-	return true;
-}
-
 /*
  * Returns the number of bytes read (removed last newline) on success.
  * Otherwise negative value is returned.
@@ -310,7 +290,7 @@ uacce_scan(void)
 			continue;
 		}
 
-		if (uacce_ignore_device(e->d_name))
+		if (rte_bus_is_ignored_device(&uacce_bus.bus, uacce_devargs_lookup(e->d_name)))
 			continue;
 
 		if (uacce_scan_one(e->d_name) < 0)
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index a787d8b18d..c386bf02c4 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -168,25 +168,6 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	return 1;
 }
 
-static bool
-vmbus_ignore_device(struct rte_vmbus_device *dev)
-{
-	struct rte_devargs *devargs = vmbus_devargs_lookup(dev);
-
-	switch (rte_vmbus_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 /*
  * Scan the vmbus, and call the devinit() function for
  * all registered drivers that have a matching entry in its id_table
@@ -205,7 +186,7 @@ rte_vmbus_probe(void)
 
 		rte_uuid_unparse(dev->device_id, ubuf, sizeof(ubuf));
 
-		if (vmbus_ignore_device(dev))
+		if (rte_bus_is_ignored_device(&rte_vmbus_bus.bus, vmbus_devargs_lookup((dev))))
 			continue;
 
 		if (vmbus_probe_all_drivers(dev) < 0) {
diff --git a/drivers/dma/idxd/idxd_bus.c b/drivers/dma/idxd/idxd_bus.c
index 9a8213bbbe..2e96039334 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -6,6 +6,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <stdbool.h>
 #include <libgen.h>
 
 #include <bus_driver.h>
@@ -247,40 +248,32 @@ idxd_probe_dsa(struct rte_dsa_device *dev)
 	return 0;
 }
 
-static int search_devargs(const char *name)
+static const struct rte_devargs *search_devargs(const char *name)
 {
 	struct rte_devargs *devargs;
 	RTE_EAL_DEVARGS_FOREACH(dsa_bus.bus.name, devargs) {
 		if (strcmp(devargs->name, name) == 0)
-			return 1;
+			return devargs;
 	}
-	return 0;
+	return NULL;
 }
 
-static int
+static bool
 is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
 {
 	char prefix[256];
-	int retval = 0;
 	size_t prefixlen;
 
 	prefixlen = rte_basename(rte_eal_get_runtime_dir(), prefix, sizeof(prefix));
 	if (prefixlen >= sizeof(prefix) || strcmp(prefix, ".") == 0)
-		return retval;
-
-	if (strncmp(name, "dpdk_", 5) == 0)
-		retval = 1;
-	if (strncmp(name, prefix, prefixlen) == 0 && name[prefixlen] == '_')
-		retval = 1;
-
-	if (retval && dsa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_UNDEFINED) {
-		if (dsa_bus.bus.conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST)
-			retval = search_devargs(dev->device.name);
-		else
-			retval = !search_devargs(dev->device.name);
+		return false;
+
+	if (strncmp(name, "dpdk_", 5) == 0 ||
+			(strncmp(name, prefix, prefixlen) == 0 && name[prefixlen] == '_')) {
+		return !rte_bus_is_ignored_device(&dsa_bus.bus, search_devargs(dev->device.name));
 	}
 
-	return retval;
+	return false;
 }
 
 static int
@@ -295,8 +288,7 @@ dsa_probe(void)
 				read_wq_string(dev, "name", name, sizeof(name)) < 0)
 			continue;
 
-		if (strncmp(type, "user", 4) == 0 &&
-				is_for_this_process_use(dev, name)) {
+		if (strncmp(type, "user", 4) == 0 && is_for_this_process_use(dev, name)) {
 			dev->device.driver = &dsa_bus.driver;
 			idxd_probe_dsa(dev);
 			continue;
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 0a2311a342..fbe20cfe35 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -8,6 +8,7 @@
 
 #include <bus_driver.h>
 #include <rte_debug.h>
+#include <rte_devargs.h>
 #include <rte_string_fns.h>
 #include <rte_errno.h>
 
@@ -226,6 +227,23 @@ rte_bus_find_by_device_name(const char *str)
 	return rte_bus_find(NULL, bus_can_parse, name);
 }
 
+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:
+		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
+			return false;
+		break;
+	case RTE_BUS_SCAN_UNDEFINED:
+	case RTE_BUS_SCAN_BLOCKLIST:
+		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
+			return false;
+		break;
+	}
+	return true;
+}
 
 /*
  * Get iommu class of devices on the bus.
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index 60527b75b6..1ec1ff57bb 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -302,6 +302,13 @@ RTE_INIT_PRIO(businitfn_ ##nm, BUS) \
 __rte_internal
 void rte_bus_unregister(struct rte_bus *bus);
 
+/**
+ * Indicate if a device referenced by some devargs should be skipped during
+ * probing of a bus.
+ */
+__rte_internal
+bool rte_bus_is_ignored_device(const struct rte_bus *bus, const struct rte_devargs *devargs);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v2 5/5] eal: configure initial device probing
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
                     ` (3 preceding siblings ...)
  2026-02-26 16:20   ` [RFC v2 4/5] bus: factorize device selection David Marchand
@ 2026-02-26 16:20   ` David Marchand
  2026-02-26 16:34     ` Bruce Richardson
  2026-02-26 16:50     ` Robin Jarry
  4 siblings, 2 replies; 40+ messages in thread
From: David Marchand @ 2026-02-26 16:20 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko

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@redhat.com>
---
Changes since RFC v1:
- changed approach following Bruce suggestion,

---
 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" };
+
 	/* 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.
+
 *   ``-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)
 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.
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [RFC v2 3/5] drivers/bus: require probe function for NXP drivers
  2026-02-26 16:20   ` [RFC v2 3/5] drivers/bus: require probe function for NXP drivers David Marchand
@ 2026-02-26 16:24     ` Bruce Richardson
  0 siblings, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-02-26 16:24 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Hemant Agrawal, Sachin Saxena

On Thu, Feb 26, 2026 at 05:20:54PM +0100, David Marchand wrote:
> Rather than silently ignore an invalid driver, enforce every registered
> driver has a probe callback.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>  drivers/bus/dpaa/dpaa_bus.c   | 6 +++---
>  drivers/bus/fslmc/fslmc_bus.c | 7 +------
>  2 files changed, 4 insertions(+), 9 deletions(-)

Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 4/5] bus: factorize device selection
  2026-02-26 16:20   ` [RFC v2 4/5] bus: factorize device selection David Marchand
@ 2026-02-26 16:31     ` Bruce Richardson
  2026-02-27 14:17       ` David Marchand
  0 siblings, 1 reply; 40+ messages in thread
From: Bruce Richardson @ 2026-02-26 16:31 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Thu, Feb 26, 2026 at 05:20:55PM +0100, David Marchand wrote:
> All buses (thankfully) implement the same logic when it comes to
> selecting the devices to probe based on -a/-b options.
> As we want to adjust how devices are selected, provide a common helper
> in EAL and use it in the buses.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>  drivers/bus/auxiliary/auxiliary_common.c | 15 +----------
>  drivers/bus/cdx/cdx.c                    | 21 +---------------
>  drivers/bus/dpaa/dpaa_bus.c              | 24 ++++++------------
>  drivers/bus/fslmc/fslmc_bus.c            | 22 ++++++----------
>  drivers/bus/pci/pci_common.c             | 15 +----------
>  drivers/bus/platform/platform.c          | 28 ++-------------------
>  drivers/bus/uacce/uacce.c                | 22 +---------------
>  drivers/bus/vmbus/vmbus_common.c         | 21 +---------------
>  drivers/dma/idxd/idxd_bus.c              | 32 +++++++++---------------
>  lib/eal/common/eal_common_bus.c          | 18 +++++++++++++
>  lib/eal/include/bus_driver.h             |  7 ++++++
>  11 files changed, 58 insertions(+), 167 deletions(-)
> 

<snip>

> diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
> index 0a2311a342..fbe20cfe35 100644
> --- a/lib/eal/common/eal_common_bus.c
> +++ b/lib/eal/common/eal_common_bus.c
> @@ -8,6 +8,7 @@
>  
>  #include <bus_driver.h>
>  #include <rte_debug.h>
> +#include <rte_devargs.h>
>  #include <rte_string_fns.h>
>  #include <rte_errno.h>
>  
> @@ -226,6 +227,23 @@ rte_bus_find_by_device_name(const char *str)
>  	return rte_bus_find(NULL, bus_can_parse, name);
>  }
>  
> +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:
> +		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
> +			return false;
> +		break;
> +	case RTE_BUS_SCAN_UNDEFINED:
> +	case RTE_BUS_SCAN_BLOCKLIST:
> +		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
> +			return false;
> +		break;
> +	}
> +	return true;
> +}

I think this could do with more comments. Am I right in thinking that
devargs is NULL on input if the device in question is not referenced by any
devargs passed to the app? This seems a little obscure form of input
parameter, so I definitely think it needs documenting.

Is there any way the search for the device name that returns the devargs
null/non-null pointer can be similarly generalized?

>  
>  /*
>   * Get iommu class of devices on the bus.
> diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
> index 60527b75b6..1ec1ff57bb 100644
> --- a/lib/eal/include/bus_driver.h
> +++ b/lib/eal/include/bus_driver.h
> @@ -302,6 +302,13 @@ RTE_INIT_PRIO(businitfn_ ##nm, BUS) \
>  __rte_internal
>  void rte_bus_unregister(struct rte_bus *bus);
>  
> +/**
> + * Indicate if a device referenced by some devargs should be skipped during
> + * probing of a bus.
> + */
> +__rte_internal
> +bool rte_bus_is_ignored_device(const struct rte_bus *bus, const struct rte_devargs *devargs);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-26 16:20   ` [RFC v2 5/5] eal: configure initial device probing David Marchand
@ 2026-02-26 16:34     ` Bruce Richardson
  2026-02-26 16:50     ` Robin Jarry
  1 sibling, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-02-26 16:34 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Thomas Monjalon, Andrew Rybchenko

On Thu, Feb 26, 2026 at 05:20:56PM +0100, David Marchand wrote:
> 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@redhat.com>
> ---
> Changes since RFC v1:
> - changed approach following Bruce suggestion,
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 1/5] devtools: check packet forwarding in null test
  2026-02-26 16:20   ` [RFC v2 1/5] devtools: check packet forwarding in null test David Marchand
@ 2026-02-26 16:35     ` Bruce Richardson
  0 siblings, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-02-26 16:35 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Thomas Monjalon, Andrew Rybchenko

On Thu, Feb 26, 2026 at 05:20:52PM +0100, David Marchand wrote:
> Add some simple checks that testpmd was indeed polling two ports, and
> some packets got through it.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>  devtools/test-null.sh | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-26 16:20   ` [RFC v2 5/5] eal: configure initial device probing David Marchand
  2026-02-26 16:34     ` Bruce Richardson
@ 2026-02-26 16:50     ` Robin Jarry
  2026-02-27 13:43       ` Thomas Monjalon
  1 sibling, 1 reply; 40+ messages in thread
From: Robin Jarry @ 2026-02-26 16:50 UTC (permalink / raw)
  To: David Marchand, dev; +Cc: Thomas Monjalon, Andrew Rybchenko

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


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-26 16:50     ` Robin Jarry
@ 2026-02-27 13:43       ` Thomas Monjalon
  2026-02-27 13:51         ` Bruce Richardson
  0 siblings, 1 reply; 40+ messages in thread
From: Thomas Monjalon @ 2026-02-27 13:43 UTC (permalink / raw)
  To: David Marchand, Robin Jarry; +Cc: dev, Andrew Rybchenko, Bruce

26/02/2026 17:50, Robin Jarry:
> 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.
[...]
> > +	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.

The name --no-autoprobe is better indeed.

The exact effect of this option is to disable initial probing
of devices on all buses (except vdev).
Another name could be --no-initial-probing

I think we should add the opposite option as well
to allow changing the default mode later.
For such an option, --autoprobe looks better than --initial-probing.

Other opinions?


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

I don't see the benefit of a short flag.
It makes reading commands less obvious.




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-27 13:43       ` Thomas Monjalon
@ 2026-02-27 13:51         ` Bruce Richardson
  2026-02-27 22:10           ` Stephen Hemminger
  0 siblings, 1 reply; 40+ messages in thread
From: Bruce Richardson @ 2026-02-27 13:51 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: David Marchand, Robin Jarry, dev, Andrew Rybchenko

On Fri, Feb 27, 2026 at 02:43:46PM +0100, Thomas Monjalon wrote:
> 26/02/2026 17:50, Robin Jarry:
> > 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.
> [...]
> > > +	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.
> 
> The name --no-autoprobe is better indeed.
> 
> The exact effect of this option is to disable initial probing
> of devices on all buses (except vdev).
> Another name could be --no-initial-probing
> 
> I think we should add the opposite option as well
> to allow changing the default mode later.
> For such an option, --autoprobe looks better than --initial-probing.
> 
> Other opinions?
> 
> 
> [...]
> > 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)
> 
> I don't see the benefit of a short flag.
> It makes reading commands less obvious.
> 
I actually would prefer to have a short option available, and I'd really
like that short option to be "-A" since it serves as the perfect addition
to the "-a" flag to specify devices to probe.

Based on that, I would look for long options which allow "-A" as the short
version for example:

--allowlisted-devs-only

/Bruce

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 4/5] bus: factorize device selection
  2026-02-26 16:31     ` Bruce Richardson
@ 2026-02-27 14:17       ` David Marchand
  2026-02-27 14:33         ` Bruce Richardson
  0 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-02-27 14:17 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Thu, 26 Feb 2026 at 17:32, Bruce Richardson
<bruce.richardson@intel.com> wrote:
> > +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:
> > +             if (devargs && devargs->policy == RTE_DEV_ALLOWED)
> > +                     return false;
> > +             break;
> > +     case RTE_BUS_SCAN_UNDEFINED:
> > +     case RTE_BUS_SCAN_BLOCKLIST:
> > +             if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
> > +                     return false;
> > +             break;
> > +     }
> > +     return true;
> > +}
>
> I think this could do with more comments. Am I right in thinking that
> devargs is NULL on input if the device in question is not referenced by any
> devargs passed to the app? This seems a little obscure form of input
> parameter, so I definitely think it needs documenting.

Yes the handling of a NULL devargs is implicit, I can add a comment.


> Is there any way the search for the device name that returns the devargs
> null/non-null pointer can be similarly generalized?

I also wondered about that and it would be better, but I stopped
quickly when I looked at the bus specific devargs_lookup functions,
preparing the v2.

For example with the pci bus, names for pci devices can take various
forms, so the pci bus uses its device specific representation for
identifying the devargs.
        rte_pci_device_name(&dev->addr,
                        dev->name, sizeof(dev->name));
        devargs = pci_devargs_lookup(&dev->addr);

And:
        RTE_EAL_DEVARGS_FOREACH("pci", devargs) {
                devargs->bus->parse(devargs->name, &addr);
                if (!rte_pci_addr_cmp(pci_addr, &addr))
                        return devargs;
        }

I suspect vmbus is the same, with this uuid stuff.

And others bus need investigation too.
I could try to normalize the devargs names for this lookup.. ?


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 4/5] bus: factorize device selection
  2026-02-27 14:17       ` David Marchand
@ 2026-02-27 14:33         ` Bruce Richardson
  0 siblings, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-02-27 14:33 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Fri, Feb 27, 2026 at 03:17:27PM +0100, David Marchand wrote:
> On Thu, 26 Feb 2026 at 17:32, Bruce Richardson
> <bruce.richardson@intel.com> wrote:
> > > +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:
> > > +             if (devargs && devargs->policy == RTE_DEV_ALLOWED)
> > > +                     return false;
> > > +             break;
> > > +     case RTE_BUS_SCAN_UNDEFINED:
> > > +     case RTE_BUS_SCAN_BLOCKLIST:
> > > +             if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
> > > +                     return false;
> > > +             break;
> > > +     }
> > > +     return true;
> > > +}
> >
> > I think this could do with more comments. Am I right in thinking that
> > devargs is NULL on input if the device in question is not referenced by any
> > devargs passed to the app? This seems a little obscure form of input
> > parameter, so I definitely think it needs documenting.
> 
> Yes the handling of a NULL devargs is implicit, I can add a comment.
> 
> 
> > Is there any way the search for the device name that returns the devargs
> > null/non-null pointer can be similarly generalized?
> 
> I also wondered about that and it would be better, but I stopped
> quickly when I looked at the bus specific devargs_lookup functions,
> preparing the v2.
> 
> For example with the pci bus, names for pci devices can take various
> forms, so the pci bus uses its device specific representation for
> identifying the devargs.
>         rte_pci_device_name(&dev->addr,
>                         dev->name, sizeof(dev->name));
>         devargs = pci_devargs_lookup(&dev->addr);
> 
> And:
>         RTE_EAL_DEVARGS_FOREACH("pci", devargs) {
>                 devargs->bus->parse(devargs->name, &addr);
>                 if (!rte_pci_addr_cmp(pci_addr, &addr))
>                         return devargs;
>         }
> 
> I suspect vmbus is the same, with this uuid stuff.
> 
> And others bus need investigation too.
> I could try to normalize the devargs names for this lookup.. ?
> 

That's a nice to have, IMHO. I think if the NULL/non-NULL is properly
commented it's good enough for this set. You can probably note the cleanup
as a TODO in the code as a further reminder.

/Bruce

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-27 13:51         ` Bruce Richardson
@ 2026-02-27 22:10           ` Stephen Hemminger
  2026-03-02  9:02             ` Bruce Richardson
  0 siblings, 1 reply; 40+ messages in thread
From: Stephen Hemminger @ 2026-02-27 22:10 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Thomas Monjalon, David Marchand, Robin Jarry, dev,
	Andrew Rybchenko

On Fri, 27 Feb 2026 13:51:48 +0000
Bruce Richardson <bruce.richardson@intel.com> wrote:

> On Fri, Feb 27, 2026 at 02:43:46PM +0100, Thomas Monjalon wrote:
> > 26/02/2026 17:50, Robin Jarry:  
> > > 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.  
> > [...]  
> > > > +	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.  
> > 
> > The name --no-autoprobe is better indeed.
> > 
> > The exact effect of this option is to disable initial probing
> > of devices on all buses (except vdev).
> > Another name could be --no-initial-probing
> > 
> > I think we should add the opposite option as well
> > to allow changing the default mode later.
> > For such an option, --autoprobe looks better than --initial-probing.
> > 
> > Other opinions?
> > 
> > 
> > [...]  
> > > 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)  
> > 
> > I don't see the benefit of a short flag.
> > It makes reading commands less obvious.
> >   
> I actually would prefer to have a short option available, and I'd really
> like that short option to be "-A" since it serves as the perfect addition
> to the "-a" flag to specify devices to probe.
> 
> Based on that, I would look for long options which allow "-A" as the short
> version for example:
> 
> --allowlisted-devs-only
> 
> /Bruce

Also if -b or --block-list become a no op with --no-autoprobe. So it should be a warning?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-02-27 22:10           ` Stephen Hemminger
@ 2026-03-02  9:02             ` Bruce Richardson
  2026-03-02 11:08               ` Morten Brørup
  2026-03-02 11:13               ` David Marchand
  0 siblings, 2 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-03-02  9:02 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Thomas Monjalon, David Marchand, Robin Jarry, dev,
	Andrew Rybchenko

On Fri, Feb 27, 2026 at 02:10:45PM -0800, Stephen Hemminger wrote:
> On Fri, 27 Feb 2026 13:51:48 +0000
> Bruce Richardson <bruce.richardson@intel.com> wrote:
> 
> > On Fri, Feb 27, 2026 at 02:43:46PM +0100, Thomas Monjalon wrote:
> > > 26/02/2026 17:50, Robin Jarry:  
> > > > 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.  
> > > [...]  
> > > > > +	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.  
> > > 
> > > The name --no-autoprobe is better indeed.
> > > 
> > > The exact effect of this option is to disable initial probing
> > > of devices on all buses (except vdev).
> > > Another name could be --no-initial-probing
> > > 
> > > I think we should add the opposite option as well
> > > to allow changing the default mode later.
> > > For such an option, --autoprobe looks better than --initial-probing.
> > > 
> > > Other opinions?
> > > 
> > > 
> > > [...]  
> > > > 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)  
> > > 
> > > I don't see the benefit of a short flag.
> > > It makes reading commands less obvious.
> > >   
> > I actually would prefer to have a short option available, and I'd really
> > like that short option to be "-A" since it serves as the perfect addition
> > to the "-a" flag to specify devices to probe.
> > 
> > Based on that, I would look for long options which allow "-A" as the short
> > version for example:
> > 
> > --allowlisted-devs-only
> > 
> > /Bruce
> 
> Also if -b or --block-list become a no op with --no-autoprobe. So it should be a warning?

Yes, I think a warning about ignored parameter would be appropriate.

/Bruce

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [RFC v2 5/5] eal: configure initial device probing
  2026-03-02  9:02             ` Bruce Richardson
@ 2026-03-02 11:08               ` Morten Brørup
  2026-03-02 11:13               ` David Marchand
  1 sibling, 0 replies; 40+ messages in thread
From: Morten Brørup @ 2026-03-02 11:08 UTC (permalink / raw)
  To: Bruce Richardson, David Marchand
  Cc: Thomas Monjalon, Robin Jarry, dev, Andrew Rybchenko,
	Stephen Hemminger

> From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> Sent: Monday, 2 March 2026 10.02
> 
> On Fri, Feb 27, 2026 at 02:10:45PM -0800, Stephen Hemminger wrote:
> > On Fri, 27 Feb 2026 13:51:48 +0000	
> > Bruce Richardson <bruce.richardson@intel.com> wrote:
> >
> > > On Fri, Feb 27, 2026 at 02:43:46PM +0100, Thomas Monjalon wrote:
> > > > 26/02/2026 17:50, Robin Jarry:
> > > > > 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.
> > > > [...]
> > > > > > +	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.
> > > >
> > > > The name --no-autoprobe is better indeed.
> > > >
> > > > The exact effect of this option is to disable initial probing
> > > > of devices on all buses (except vdev).
> > > > Another name could be --no-initial-probing
> > > >
> > > > I think we should add the opposite option as well
> > > > to allow changing the default mode later.
> > > > For such an option, --autoprobe looks better than --initial-
> probing.
> > > >
> > > > Other opinions?
> > > >
> > > >
> > > > [...]
> > > > > 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)
> > > >
> > > > I don't see the benefit of a short flag.
> > > > It makes reading commands less obvious.
> > > >
> > > I actually would prefer to have a short option available, and I'd
> really
> > > like that short option to be "-A" since it serves as the perfect
> addition
> > > to the "-a" flag to specify devices to probe.
> > >
> > > Based on that, I would look for long options which allow "-A" as
> the short
> > > version for example:
> > >
> > > --allowlisted-devs-only
> > >
> > > /Bruce
> >
> > Also if -b or --block-list become a no op with --no-autoprobe. So it
> should be a warning?
> 
> Yes, I think a warning about ignored parameter would be appropriate.
> 
> /Bruce

I haven't been following this discussion, so I might me completely off here.

IIUC, this option is used for specifying which devices to probe.
(And as a side effect disables auto-probing of all devices.)

When naming it, please take a fresh view.
Imagine you are defining this option and an auto-probe option.

The discussion assumes the user is familiar with auto-probe, and expects auto-probe. Don't design based on that.

-Morten


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v2 5/5] eal: configure initial device probing
  2026-03-02  9:02             ` Bruce Richardson
  2026-03-02 11:08               ` Morten Brørup
@ 2026-03-02 11:13               ` David Marchand
  1 sibling, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-02 11:13 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Stephen Hemminger, Thomas Monjalon, Robin Jarry, dev,
	Andrew Rybchenko

On Mon, 2 Mar 2026 at 10:04, Bruce Richardson
<bruce.richardson@intel.com> wrote:
> > > > > Or:
> > > > >
> > > > > BOOL_ARG("--no-autoprobe", "-P", "Disable automatic probing of non-blocked devices", no_autoprobe)
> > > >
> > > > I don't see the benefit of a short flag.
> > > > It makes reading commands less obvious.
> > > >
> > > I actually would prefer to have a short option available, and I'd really
> > > like that short option to be "-A" since it serves as the perfect addition
> > > to the "-a" flag to specify devices to probe.
> > >
> > > Based on that, I would look for long options which allow "-A" as the short
> > > version for example:
> > >
> > > --allowlisted-devs-only

--allow-only?


> > >
> > > /Bruce
> >
> > Also if -b or --block-list become a no op with --no-autoprobe. So it should be a warning?
>
> Yes, I think a warning about ignored parameter would be appropriate.

Thomas had the same comment when we talked about the series.
However, I would reject the combination rather than warn.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [RFC v3 0/7] Rework device probing
  2026-02-25 11:29 [RFC 1/2] devtools: check packet forwarding in null test David Marchand
  2026-02-25 11:29 ` [RFC 2/2] eal: configure initial device probing David Marchand
  2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
@ 2026-03-05 16:45 ` David Marchand
  2026-03-05 16:45   ` [RFC v3 1/7] devtools: check packet forwarding in null test David Marchand
                     ` (7 more replies)
  2 siblings, 8 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev

Applications relying on device hotplug don't work well with the default
probing of all available resources.
This series proposes to change this behavior via a new EAL option.


-- 
David Marchand

Changes since RFC v2:
- went one step further and reworked devargs lookup in buses following
  Bruce comment (see patch 4 which is cosmetic, and patch 5),
- updated device selection helper accordingly and
  changed API to be device name based,
- renamed option, added check on -b presence, updated doc in the last
  patch,

Changes since RFC v1:
- reviewed bus probe() and cleaned up NXP drivers,
- changed approach following Bruce comment,

David Marchand (7):
  devtools: check packet forwarding in null test
  bus/fslmc: fix bus cleanup
  drivers/bus: require probe function for NXP drivers
  drivers: cleanup devargs lookup in bus scan
  bus: factorize devargs lookup
  bus: factorize device selection
  eal: configure initial device probing

 app/test/test_eal_flags.c                    | 63 +++++++++++++++++
 devtools/test-null.sh                        | 10 ++-
 doc/guides/linux_gsg/eal_args.include.rst    | 13 ++++
 drivers/bus/auxiliary/auxiliary_common.c     | 33 +--------
 drivers/bus/auxiliary/bus_auxiliary_driver.h |  2 -
 drivers/bus/auxiliary/linux/auxiliary.c      |  2 +-
 drivers/bus/auxiliary/private.h              |  6 --
 drivers/bus/cdx/cdx.c                        | 34 +---------
 drivers/bus/dpaa/dpaa_bus.c                  | 71 +++++++++-----------
 drivers/bus/fslmc/fslmc_bus.c                | 69 ++++++++-----------
 drivers/bus/fslmc/fslmc_vfio.c               | 22 ++----
 drivers/bus/ifpga/bus_ifpga_driver.h         |  2 -
 drivers/bus/ifpga/ifpga_bus.c                |  4 +-
 drivers/bus/pci/bsd/pci.c                    |  5 +-
 drivers/bus/pci/linux/pci.c                  |  2 +-
 drivers/bus/pci/pci_common.c                 | 51 ++++----------
 drivers/bus/pci/private.h                    | 11 ---
 drivers/bus/pci/windows/pci.c                |  4 +-
 drivers/bus/platform/platform.c              | 43 +-----------
 drivers/bus/uacce/uacce.c                    | 39 +----------
 drivers/bus/vdev/vdev.c                      |  2 +-
 drivers/bus/vmbus/linux/vmbus_bus.c          |  2 +-
 drivers/bus/vmbus/private.h                  |  3 -
 drivers/bus/vmbus/vmbus_common.c             | 45 +++----------
 drivers/dma/idxd/idxd_bus.c                  | 18 +----
 drivers/raw/ifpga/ifpga_rawdev.c             |  2 +-
 lib/eal/common/eal_common_bus.c              | 44 ++++++++++++
 lib/eal/common/eal_common_options.c          | 10 +++
 lib/eal/common/eal_internal_cfg.h            |  1 +
 lib/eal/common/eal_option_list.h             |  2 +
 lib/eal/include/bus_driver.h                 | 37 ++++++++++
 31 files changed, 288 insertions(+), 364 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [RFC v3 1/7] devtools: check packet forwarding in null test
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 16:45   ` [RFC v3 2/7] bus/fslmc: fix bus cleanup David Marchand
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Thomas Monjalon, Andrew Rybchenko

Add some simple checks that testpmd was indeed polling two ports, and
some packets got through it.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
 devtools/test-null.sh | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/devtools/test-null.sh b/devtools/test-null.sh
index e3ac168ce3..8f21189262 100755
--- a/devtools/test-null.sh
+++ b/devtools/test-null.sh
@@ -26,8 +26,14 @@ else
 	libs=
 fi
 
+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 -- \
-	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia
+	--no-mlockall --total-num-mbufs=2048 $testpmd_options -ia | tee $logfile
+
+# we expect two ports and some traffic is received and transmitted
+grep -q 'io packet forwarding - ports=2 -' $build/test-null.log
+grep 'RX-packets: ' $logfile | tail -1 | grep -q 'RX-packets:[[:space:]]*[^0[:space:]]'
+grep 'TX-packets: ' $logfile | tail -1 | grep -q 'TX-packets:[[:space:]]*[^0[:space:]]'
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 2/7] bus/fslmc: fix bus cleanup
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
  2026-03-05 16:45   ` [RFC v3 1/7] devtools: check packet forwarding in null test David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 16:45   ` [RFC v3 3/7] drivers/bus: require probe function for NXP drivers David Marchand
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev; +Cc: stable, Hemant Agrawal, Sachin Saxena, Rohit Raj

The close operation was never closing probed devices.

Taking a step back, reevaluating the devargs makes no sense during the
close step, as a probed device must have passed the allow/block list
evaluation initially.

Since the device contains a reference to the driver that probed it,
simply call this driver remove op.

Fixes: 274fd921ff7f ("bus/fslmc: support close operation")
Cc: stable@dpdk.org

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/fslmc/fslmc_vfio.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 550d4e0e8d..481bad196b 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -1393,7 +1393,7 @@ fslmc_close_iodevices(struct rte_dpaa2_device *dev,
 {
 	struct rte_dpaa2_object *object = NULL;
 	struct rte_dpaa2_driver *drv;
-	int ret, probe_all;
+	int ret;
 
 	switch (dev->dev_type) {
 	case DPAA2_IO:
@@ -1411,21 +1411,11 @@ fslmc_close_iodevices(struct rte_dpaa2_device *dev,
 	case DPAA2_ETH:
 	case DPAA2_CRYPTO:
 	case DPAA2_QDMA:
-		probe_all = rte_fslmc_bus.bus.conf.scan_mode !=
-			    RTE_BUS_SCAN_ALLOWLIST;
-		TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
-			if (drv->drv_type != dev->dev_type)
-				continue;
-			if (rte_dev_is_probed(&dev->device))
-				continue;
-			if (probe_all ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy ==
-			     RTE_DEV_ALLOWED)) {
-				ret = drv->remove(dev);
-				if (ret)
-					DPAA2_BUS_ERR("Unable to remove");
-			}
+		drv = dev->driver;
+		if (drv && drv->remove) {
+			ret = drv->remove(dev);
+			if (ret)
+				DPAA2_BUS_ERR("Unable to remove");
 		}
 		break;
 	default:
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 3/7] drivers/bus: require probe function for NXP drivers
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
  2026-03-05 16:45   ` [RFC v3 1/7] devtools: check packet forwarding in null test David Marchand
  2026-03-05 16:45   ` [RFC v3 2/7] bus/fslmc: fix bus cleanup David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 16:45   ` [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan David Marchand
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Hemant Agrawal, Sachin Saxena

Rather than silently ignore an invalid driver, enforce every registered
driver has a probe callback.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/bus/dpaa/dpaa_bus.c   | 6 +++---
 drivers/bus/fslmc/fslmc_bus.c | 7 +------
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index d9830b68ca..5e0f32bfe8 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -614,6 +614,7 @@ void
 rte_dpaa_driver_register(struct rte_dpaa_driver *driver)
 {
 	RTE_VERIFY(driver);
+	RTE_VERIFY(driver->probe != NULL);
 
 	BUS_INIT_FUNC_TRACE();
 
@@ -808,9 +809,8 @@ rte_dpaa_bus_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (!drv->probe ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy == RTE_DEV_BLOCKED))
+			if (dev->device.devargs &&
+			    dev->device.devargs->policy == RTE_DEV_BLOCKED)
 				continue;
 
 			if (probe_all ||
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index abdb0ad50d..ac9fb7a08c 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -465,9 +465,6 @@ rte_fslmc_probe(void)
 			if (ret)
 				continue;
 
-			if (!drv->probe)
-				continue;
-
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
@@ -534,6 +531,7 @@ void
 rte_fslmc_driver_register(struct rte_dpaa2_driver *driver)
 {
 	RTE_VERIFY(driver);
+	RTE_VERIFY(driver->probe != NULL);
 
 	TAILQ_INSERT_TAIL(&rte_fslmc_bus.driver_list, driver, next);
 }
@@ -601,9 +599,6 @@ fslmc_bus_plug(struct rte_device *rte_dev)
 		if (ret)
 			continue;
 
-		if (!drv->probe)
-			continue;
-
 		if (rte_dev_is_probed(&dev->device))
 			continue;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
                     ` (2 preceding siblings ...)
  2026-03-05 16:45   ` [RFC v3 3/7] drivers/bus: require probe function for NXP drivers David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 16:56     ` Bruce Richardson
  2026-03-05 16:45   ` [RFC v3 5/7] bus: factorize devargs lookup David Marchand
                     ` (3 subsequent siblings)
  7 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev
  Cc: Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Rosen Xu, Chenbo Xia,
	Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu

Don't hardcode the bus names in the RTE_EAL_DEVARGS_FOREACH() calls.
The bus name is set by code in EAL.
Even if there is nothing broken, let's reuse the name from the bus object.

And remove the now useless macros.

Note: in the ifpga bus case, the call was using an incorrect macro
(IFPGA_ARG_NAME instead of IFPGA_BUS_NAME), yet it was working fine
as this macro is aligned with the ifpga bus name.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/auxiliary/auxiliary_common.c     | 2 +-
 drivers/bus/auxiliary/bus_auxiliary_driver.h | 2 --
 drivers/bus/cdx/cdx.c                        | 3 +--
 drivers/bus/dpaa/dpaa_bus.c                  | 6 ++----
 drivers/bus/fslmc/fslmc_bus.c                | 8 +++-----
 drivers/bus/ifpga/bus_ifpga_driver.h         | 2 --
 drivers/bus/ifpga/ifpga_bus.c                | 4 ++--
 drivers/bus/pci/pci_common.c                 | 2 +-
 drivers/bus/platform/platform.c              | 2 +-
 drivers/bus/uacce/uacce.c                    | 2 +-
 drivers/bus/vdev/vdev.c                      | 2 +-
 drivers/bus/vmbus/vmbus_common.c             | 2 +-
 drivers/raw/ifpga/ifpga_rawdev.c             | 2 +-
 13 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index ac766e283e..119533df28 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -30,7 +30,7 @@ auxiliary_devargs_lookup(const char *name)
 {
 	struct rte_devargs *devargs;
 
-	RTE_EAL_DEVARGS_FOREACH(RTE_BUS_AUXILIARY_NAME, devargs) {
+	RTE_EAL_DEVARGS_FOREACH(auxiliary_bus.bus.name, devargs) {
 		if (strcmp(devargs->name, name) == 0)
 			return devargs;
 	}
diff --git a/drivers/bus/auxiliary/bus_auxiliary_driver.h b/drivers/bus/auxiliary/bus_auxiliary_driver.h
index 1dc814151e..8450d56583 100644
--- a/drivers/bus/auxiliary/bus_auxiliary_driver.h
+++ b/drivers/bus/auxiliary/bus_auxiliary_driver.h
@@ -28,8 +28,6 @@
 extern "C" {
 #endif
 
-#define RTE_BUS_AUXILIARY_NAME "auxiliary"
-
 /* Forward declarations */
 struct rte_auxiliary_driver;
 struct rte_auxiliary_device;
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index 729d54337c..b183d98453 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -82,7 +82,6 @@
 #include "cdx_logs.h"
 #include "private.h"
 
-#define CDX_BUS_NAME	cdx
 #define CDX_DEV_PREFIX	"cdx-"
 
 /* CDX Bus iterators */
@@ -157,7 +156,7 @@ cdx_devargs_lookup(const char *dev_name)
 {
 	struct rte_devargs *devargs;
 
-	RTE_EAL_DEVARGS_FOREACH("cdx", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_cdx_bus.bus.name, devargs) {
 		if (strcmp(devargs->name, dev_name) == 0)
 			return devargs;
 	}
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 5e0f32bfe8..e3c17d41f7 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -77,8 +77,6 @@ static pthread_key_t dpaa_portal_key;
 struct dpaa_portal *dpaa_portals[RTE_MAX_LCORE] = {NULL};
 static int dpaa_bus_global_init;
 
-#define FSL_DPAA_BUS_NAME	dpaa_bus
-
 RTE_EXPORT_INTERNAL_SYMBOL(per_lcore_dpaa_io)
 RTE_DEFINE_PER_LCORE(struct dpaa_portal *, dpaa_io);
 
@@ -206,7 +204,7 @@ dpaa_devargs_lookup(struct rte_dpaa_device *dev)
 	struct rte_devargs *devargs;
 	char dev_name[32];
 
-	RTE_EAL_DEVARGS_FOREACH("dpaa_bus", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_dpaa_bus.bus.name, devargs) {
 		devargs->bus->parse(devargs->name, &dev_name);
 		if (strcmp(dev_name, dev->device.name) == 0) {
 			DPAA_BUS_INFO("**Devargs matched %s", dev_name);
@@ -1003,5 +1001,5 @@ static struct rte_dpaa_bus rte_dpaa_bus = {
 	.device_count = 0,
 };
 
-RTE_REGISTER_BUS(FSL_DPAA_BUS_NAME, rte_dpaa_bus.bus);
+RTE_REGISTER_BUS(dpaa_bus, rte_dpaa_bus.bus);
 RTE_LOG_REGISTER_DEFAULT(dpaa_logtype_bus, NOTICE);
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index ac9fb7a08c..8f3e3dc1be 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -26,7 +26,6 @@
 #include <dpaax_iova_table.h>
 
 #define VFIO_IOMMU_GROUP_PATH "/sys/kernel/iommu_groups"
-#define FSLMC_BUS_NAME	fslmc
 
 struct rte_fslmc_bus rte_fslmc_bus;
 
@@ -106,7 +105,7 @@ fslmc_devargs_lookup(struct rte_dpaa2_device *dev)
 	struct rte_devargs *devargs;
 	char dev_name[32];
 
-	RTE_EAL_DEVARGS_FOREACH("fslmc", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_fslmc_bus.bus.name, devargs) {
 		devargs->bus->parse(devargs->name, &dev_name);
 		if (strcmp(dev_name, dev->device.name) == 0) {
 			DPAA2_BUS_INFO("**Devargs matched %s", dev_name);
@@ -266,8 +265,7 @@ rte_fslmc_parse(const char *name, void *addr)
 	 */
 	if (sep_exists) {
 		/* If either of "fslmc" or "name" are starting part */
-		if (!strncmp(name, RTE_STR(FSLMC_BUS_NAME),
-			     strlen(RTE_STR(FSLMC_BUS_NAME))) ||
+		if (!strncmp(name, rte_fslmc_bus.bus.name, strlen(rte_fslmc_bus.bus.name)) ||
 		   (!strncmp(name, "name", strlen("name")))) {
 			goto jump_out;
 		} else {
@@ -704,5 +702,5 @@ struct rte_fslmc_bus rte_fslmc_bus = {
 	.device_count = {0},
 };
 
-RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus);
+RTE_REGISTER_BUS(fslmc, rte_fslmc_bus.bus);
 RTE_LOG_REGISTER_DEFAULT(dpaa2_logtype_bus, NOTICE);
diff --git a/drivers/bus/ifpga/bus_ifpga_driver.h b/drivers/bus/ifpga/bus_ifpga_driver.h
index d34ab8cec1..5e77a8f170 100644
--- a/drivers/bus/ifpga/bus_ifpga_driver.h
+++ b/drivers/bus/ifpga/bus_ifpga_driver.h
@@ -21,8 +21,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#define IFPGA_BUS_NAME ifpga
-
 /* Forward declarations */
 struct rte_afu_device;
 struct rte_afu_driver;
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index fdce1f6b1f..2692a09d15 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -220,7 +220,7 @@ ifpga_scan(void)
 	struct rte_afu_device *afu_dev = NULL;
 
 	/* for FPGA devices we scan the devargs_list populated via cmdline */
-	RTE_EAL_DEVARGS_FOREACH(IFPGA_ARG_NAME, devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_ifpga_bus.name, devargs) {
 		if (devargs->bus != &rte_ifpga_bus)
 			continue;
 
@@ -516,5 +516,5 @@ static struct rte_bus rte_ifpga_bus = {
 	.parse       = ifpga_parse,
 };
 
-RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus);
+RTE_REGISTER_BUS(ifpga, rte_ifpga_bus);
 RTE_LOG_REGISTER_DEFAULT(ifpga_bus_logtype, NOTICE);
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index bf5df3d94e..1d26fce680 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -85,7 +85,7 @@ pci_devargs_lookup(const struct rte_pci_addr *pci_addr)
 	struct rte_devargs *devargs;
 	struct rte_pci_addr addr;
 
-	RTE_EAL_DEVARGS_FOREACH("pci", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_pci_bus.bus.name, devargs) {
 		devargs->bus->parse(devargs->name, &addr);
 		if (!rte_pci_addr_cmp(pci_addr, &addr))
 			return devargs;
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index f6673cf181..18fa73795c 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -48,7 +48,7 @@ dev_devargs(const char *dev_name)
 {
 	struct rte_devargs *devargs;
 
-	RTE_EAL_DEVARGS_FOREACH("platform", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(platform_bus.bus.name, devargs) {
 		if (!strcmp(devargs->name, dev_name))
 			return devargs;
 	}
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 79f990c54c..1998b0c518 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -76,7 +76,7 @@ uacce_devargs_lookup(const char *dev_name)
 	struct rte_devargs *devargs;
 
 	snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
-	RTE_EAL_DEVARGS_FOREACH("uacce", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(uacce_bus.bus.name, devargs) {
 		if (strcmp(devargs->name, name) == 0)
 			return devargs;
 	}
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index be375f63dc..eb1de0186e 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -526,7 +526,7 @@ vdev_scan(void)
 	rte_spinlock_unlock(&vdev_custom_scan_lock);
 
 	/* for virtual devices we scan the devargs_list populated via cmdline */
-	RTE_EAL_DEVARGS_FOREACH("vdev", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_vdev_bus.name, devargs) {
 
 		dev = calloc(1, sizeof(*dev));
 		if (!dev)
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index a787d8b18d..f857244c85 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -271,7 +271,7 @@ vmbus_devargs_lookup(struct rte_vmbus_device *dev)
 	struct rte_devargs *devargs;
 	rte_uuid_t addr;
 
-	RTE_EAL_DEVARGS_FOREACH("vmbus", devargs) {
+	RTE_EAL_DEVARGS_FOREACH(rte_vmbus_bus.bus.name, devargs) {
 		vmbus_parse(devargs->name, &addr);
 
 		if (rte_uuid_compare(dev->device_id, addr) == 0)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 5b9b596435..01e9427d53 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -1823,7 +1823,7 @@ ifpga_cfg_probe(struct rte_vdev_device *vdev)
 
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 		args.port, args.bdf);
-	ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME),
+	ret = rte_eal_hotplug_add(vdev->device.devargs->bus->name,
 			dev_name, vdev->device.devargs->args);
 	if (ret) {
 		rte_free(ifpga_dev->vdev_name[i]);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 5/7] bus: factorize devargs lookup
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
                     ` (3 preceding siblings ...)
  2026-03-05 16:45   ` [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 17:06     ` Bruce Richardson
  2026-03-05 16:45   ` [RFC v3 6/7] bus: factorize device selection David Marchand
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev
  Cc: Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Bruce Richardson, Kevin Laatz

Each bus reimplements some similar devargs lookup code.

The differences are in how some bus (PCI, VMBUS etc...) normalizes the
device names. We can't use the .parse existing handler from outside the
bus code itself, as the size of the bus specific device location address
is unknown.
Introduce a bus specific helper to compare two device names and
hide this ugly detail.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/auxiliary/auxiliary_common.c | 16 ++-------
 drivers/bus/cdx/cdx.c                    | 14 +-------
 drivers/bus/dpaa/dpaa_bus.c              | 41 +++++++++++++-----------
 drivers/bus/fslmc/fslmc_bus.c            | 34 ++++++++++----------
 drivers/bus/pci/pci_common.c             | 38 +++++++++++-----------
 drivers/bus/platform/platform.c          | 17 ++--------
 drivers/bus/uacce/uacce.c                | 19 ++---------
 drivers/bus/vmbus/linux/vmbus_bus.c      |  2 +-
 drivers/bus/vmbus/private.h              |  3 --
 drivers/bus/vmbus/vmbus_common.c         | 30 ++++++++---------
 drivers/dma/idxd/idxd_bus.c              | 14 ++------
 lib/eal/common/eal_common_bus.c          | 20 ++++++++++++
 lib/eal/include/bus_driver.h             | 31 ++++++++++++++++++
 13 files changed, 132 insertions(+), 147 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index 119533df28..e5b4f4460d 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -25,18 +25,6 @@
 
 #include "private.h"
 
-static struct rte_devargs *
-auxiliary_devargs_lookup(const char *name)
-{
-	struct rte_devargs *devargs;
-
-	RTE_EAL_DEVARGS_FOREACH(auxiliary_bus.bus.name, devargs) {
-		if (strcmp(devargs->name, name) == 0)
-			return devargs;
-	}
-	return NULL;
-}
-
 #ifndef AUXILIARY_OS_SUPPORTED
 /*
  * Test whether the auxiliary device exist.
@@ -68,7 +56,7 @@ auxiliary_scan(void)
 void
 auxiliary_on_scan(struct rte_auxiliary_device *aux_dev)
 {
-	aux_dev->device.devargs = auxiliary_devargs_lookup(aux_dev->name);
+	aux_dev->device.devargs = rte_bus_find_devargs(&auxiliary_bus.bus, aux_dev->name);
 }
 
 /*
@@ -399,7 +387,7 @@ auxiliary_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
 bool
 auxiliary_is_ignored_device(const char *name)
 {
-	struct rte_devargs *devargs = auxiliary_devargs_lookup(name);
+	struct rte_devargs *devargs = rte_bus_find_devargs(&auxiliary_bus.bus, name);
 
 	switch (auxiliary_bus.bus.conf.scan_mode) {
 	case RTE_BUS_SCAN_ALLOWLIST:
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index b183d98453..0801825ef5 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -151,22 +151,10 @@ void rte_cdx_unmap_device(struct rte_cdx_device *dev)
 	cdx_vfio_unmap_resource(dev);
 }
 
-static struct rte_devargs *
-cdx_devargs_lookup(const char *dev_name)
-{
-	struct rte_devargs *devargs;
-
-	RTE_EAL_DEVARGS_FOREACH(rte_cdx_bus.bus.name, devargs) {
-		if (strcmp(devargs->name, dev_name) == 0)
-			return devargs;
-	}
-	return NULL;
-}
-
 static bool
 cdx_ignore_device(const char *dev_name)
 {
-	struct rte_devargs *devargs = cdx_devargs_lookup(dev_name);
+	struct rte_devargs *devargs = rte_bus_find_devargs(&rte_cdx_bus.bus, dev_name);
 
 	switch (rte_cdx_bus.bus.conf.scan_mode) {
 	case RTE_BUS_SCAN_ALLOWLIST:
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index e3c17d41f7..356c56d989 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -198,22 +198,6 @@ dpaa_sec_available(void)
 
 static void dpaa_clean_device_list(void);
 
-static struct rte_devargs *
-dpaa_devargs_lookup(struct rte_dpaa_device *dev)
-{
-	struct rte_devargs *devargs;
-	char dev_name[32];
-
-	RTE_EAL_DEVARGS_FOREACH(rte_dpaa_bus.bus.name, devargs) {
-		devargs->bus->parse(devargs->name, &dev_name);
-		if (strcmp(dev_name, dev->device.name) == 0) {
-			DPAA_BUS_INFO("**Devargs matched %s", dev_name);
-			return devargs;
-		}
-	}
-	return NULL;
-}
-
 static int
 dpaa_create_device_list(void)
 {
@@ -269,7 +253,9 @@ dpaa_create_device_list(void)
 				(fman_intf->fman->idx + 1), fman_intf->mac_idx);
 		}
 		dev->device.name = dev->name;
-		dev->device.devargs = dpaa_devargs_lookup(dev);
+		dev->device.devargs = rte_bus_find_devargs(&rte_dpaa_bus.bus, dev->name);
+		if (dev->device.devargs != NULL)
+			DPAA_BUS_INFO("**Devargs matched %s", dev->name);
 
 		dpaa_add_to_device_list(dev);
 	}
@@ -317,7 +303,9 @@ dpaa_create_device_list(void)
 		sprintf(dev->name, "dpaa_sec-%d", i+1);
 		DPAA_BUS_LOG(INFO, "%s cryptodev added", dev->name);
 		dev->device.name = dev->name;
-		dev->device.devargs = dpaa_devargs_lookup(dev);
+		dev->device.devargs = rte_bus_find_devargs(&rte_dpaa_bus.bus, dev->name);
+		if (dev->device.devargs != NULL)
+			DPAA_BUS_INFO("**Devargs matched %s", dev->name);
 
 		dpaa_add_to_device_list(dev);
 	}
@@ -341,7 +329,9 @@ dpaa_create_device_list(void)
 		sprintf(dev->name, "dpaa_qdma-%d", i+1);
 		DPAA_BUS_LOG(INFO, "%s qdma device added", dev->name);
 		dev->device.name = dev->name;
-		dev->device.devargs = dpaa_devargs_lookup(dev);
+		dev->device.devargs = rte_bus_find_devargs(&rte_dpaa_bus.bus, dev->name);
+		if (dev->device.devargs != NULL)
+			DPAA_BUS_INFO("**Devargs matched %s", dev->name);
 
 		dpaa_add_to_device_list(dev);
 	}
@@ -572,6 +562,18 @@ rte_dpaa_bus_parse(const char *name, void *out)
 	return 0;
 }
 
+static int
+dpaa_bus_devname_compare(const char *name1, const char *name2)
+{
+	char devname1[32], devname2[32];
+
+	if (rte_dpaa_bus_parse(name1, devname1) != 0 ||
+			rte_dpaa_bus_parse(name2, devname2) != 0)
+		return 1;
+
+	return strncmp(devname1, devname2, sizeof(devname1));
+}
+
 #define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
 #define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
 
@@ -988,6 +990,7 @@ static struct rte_dpaa_bus rte_dpaa_bus = {
 		.scan = rte_dpaa_bus_scan,
 		.probe = rte_dpaa_bus_probe,
 		.parse = rte_dpaa_bus_parse,
+		.devname_compare = dpaa_bus_devname_compare,
 		.find_device = rte_dpaa_find_device,
 		.get_iommu_class = rte_dpaa_get_iommu_class,
 		.plug = dpaa_bus_plug,
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 8f3e3dc1be..f72b512b1a 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -99,22 +99,6 @@ insert_in_device_list(struct rte_dpaa2_device *newdev)
 		TAILQ_INSERT_TAIL(&rte_fslmc_bus.device_list, newdev, next);
 }
 
-static struct rte_devargs *
-fslmc_devargs_lookup(struct rte_dpaa2_device *dev)
-{
-	struct rte_devargs *devargs;
-	char dev_name[32];
-
-	RTE_EAL_DEVARGS_FOREACH(rte_fslmc_bus.bus.name, devargs) {
-		devargs->bus->parse(devargs->name, &dev_name);
-		if (strcmp(dev_name, dev->device.name) == 0) {
-			DPAA2_BUS_INFO("**Devargs matched %s", dev_name);
-			return devargs;
-		}
-	}
-	return NULL;
-}
-
 static void
 dump_device_list(void)
 {
@@ -216,7 +200,10 @@ scan_one_fslmc_device(char *dev_name)
 		ret = -ENOMEM;
 		goto cleanup;
 	}
-	dev->device.devargs = fslmc_devargs_lookup(dev);
+	dev->device.devargs = rte_bus_find_devargs(&rte_fslmc_bus.bus, dev_name);
+	if (dev->device.devargs != NULL)
+		DPAA2_BUS_INFO("**Devargs matched %s", dev_name);
+
 
 	/* Update the device found into the device_count table */
 	rte_fslmc_bus.device_count[dev->dev_type]++;
@@ -308,6 +295,18 @@ rte_fslmc_parse(const char *name, void *addr)
 	return ret;
 }
 
+static int
+fslmc_devname_compare(const char *name1, const char *name2)
+{
+	char devname1[32], devname2[32];
+
+	if (rte_fslmc_parse(name1, devname1) != 0 ||
+			rte_fslmc_parse(name2, devname2) != 0)
+		return 1;
+
+	return strncmp(devname1, devname2, sizeof(devname1));
+}
+
 static int
 rte_fslmc_scan(void)
 {
@@ -691,6 +690,7 @@ struct rte_fslmc_bus rte_fslmc_bus = {
 		.probe = rte_fslmc_probe,
 		.cleanup = rte_fslmc_close,
 		.parse = rte_fslmc_parse,
+		.devname_compare = fslmc_devname_compare,
 		.find_device = rte_fslmc_find_device,
 		.get_iommu_class = rte_dpaa2_get_iommu_class,
 		.plug = fslmc_bus_plug,
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 1d26fce680..8782dc342a 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -79,32 +79,15 @@ pci_asprintf(char **buffer, const char *format, ...)
 }
 #endif /* RTE_EXEC_ENV_WINDOWS */
 
-static struct rte_devargs *
-pci_devargs_lookup(const struct rte_pci_addr *pci_addr)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-
-	RTE_EAL_DEVARGS_FOREACH(rte_pci_bus.bus.name, devargs) {
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_pci_addr_cmp(pci_addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
 void
 pci_common_set(struct rte_pci_device *dev)
 {
-	struct rte_devargs *devargs;
-
 	/* Each device has its internal, canonical name set. */
 	rte_pci_device_name(&dev->addr,
 			dev->name, sizeof(dev->name));
 	dev->device.name = dev->name;
 
-	devargs = pci_devargs_lookup(&dev->addr);
-	dev->device.devargs = devargs;
+	dev->device.devargs = rte_bus_find_devargs(&rte_pci_bus.bus, dev->name);
 
 	if (dev->bus_info != NULL ||
 			asprintf(&dev->bus_info, "vendor_id=%"PRIx16", device_id=%"PRIx16,
@@ -503,6 +486,18 @@ pci_parse(const char *name, void *addr)
 	return parse == false;
 }
 
+static int
+pci_devname_compare(const char *name1, const char *name2)
+{
+	struct rte_pci_addr addr1, addr2;
+
+	if (rte_pci_addr_parse(name1, &addr1) != 0 ||
+			rte_pci_addr_parse(name2, &addr2) != 0)
+		return 1;
+
+	return rte_pci_addr_cmp(&addr1, &addr2);
+}
+
 /* register a driver */
 RTE_EXPORT_INTERNAL_SYMBOL(rte_pci_register)
 void
@@ -721,7 +716,11 @@ pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 bool
 rte_pci_ignore_device(const struct rte_pci_addr *pci_addr)
 {
-	struct rte_devargs *devargs = pci_devargs_lookup(pci_addr);
+	char name[RTE_DEV_NAME_MAX_LEN];
+	struct rte_devargs *devargs;
+
+	rte_pci_device_name(pci_addr, name, sizeof(name));
+	devargs = rte_bus_find_devargs(&rte_pci_bus.bus, name);
 
 	switch (rte_pci_bus.bus.conf.scan_mode) {
 	case RTE_BUS_SCAN_ALLOWLIST:
@@ -946,6 +945,7 @@ struct rte_pci_bus rte_pci_bus = {
 		.plug = pci_plug,
 		.unplug = pci_unplug,
 		.parse = pci_parse,
+		.devname_compare = pci_devname_compare,
 		.devargs_parse = rte_pci_devargs_parse,
 		.dma_map = pci_dma_map,
 		.dma_unmap = pci_dma_unmap,
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 18fa73795c..23c39aada6 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -43,25 +43,12 @@ rte_platform_unregister(struct rte_platform_driver *pdrv)
 	TAILQ_REMOVE(&platform_bus.driver_list, pdrv, next);
 }
 
-static struct rte_devargs *
-dev_devargs(const char *dev_name)
-{
-	struct rte_devargs *devargs;
-
-	RTE_EAL_DEVARGS_FOREACH(platform_bus.bus.name, devargs) {
-		if (!strcmp(devargs->name, dev_name))
-			return devargs;
-	}
-
-	return NULL;
-}
-
 static bool
 dev_allowed(const char *dev_name)
 {
 	struct rte_devargs *devargs;
 
-	devargs = dev_devargs(dev_name);
+	devargs = rte_bus_find_devargs(&platform_bus.bus, dev_name);
 	if (devargs == NULL)
 		return true;
 
@@ -93,7 +80,7 @@ dev_add(const char *dev_name)
 
 	rte_strscpy(pdev->name, dev_name, sizeof(pdev->name));
 	pdev->device.name = pdev->name;
-	pdev->device.devargs = dev_devargs(dev_name);
+	pdev->device.devargs = rte_bus_find_devargs(&platform_bus.bus, dev_name);
 	pdev->device.bus = &platform_bus.bus;
 	snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/numa_node", dev_name);
 	pdev->device.numa_node = eal_parse_sysfs_value(path, &val) ? rte_socket_id() : val;
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 1998b0c518..1a3deea31a 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -69,25 +69,10 @@ extern int uacce_bus_logtype;
 #define UACCE_BUS_DEBUG(fmt, ...) UACCE_BUS_LOG(DEBUG, fmt, ##__VA_ARGS__)
 
 
-static struct rte_devargs *
-uacce_devargs_lookup(const char *dev_name)
-{
-	char name[RTE_UACCE_DEV_PATH_SIZE] = {0};
-	struct rte_devargs *devargs;
-
-	snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
-	RTE_EAL_DEVARGS_FOREACH(uacce_bus.bus.name, devargs) {
-		if (strcmp(devargs->name, name) == 0)
-			return devargs;
-	}
-
-	return NULL;
-}
-
 static bool
 uacce_ignore_device(const char *dev_name)
 {
-	struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
+	struct rte_devargs *devargs = rte_bus_find_devargs(&uacce_bus.bus, dev_name);
 
 	switch (uacce_bus.bus.conf.scan_mode) {
 	case RTE_BUS_SCAN_ALLOWLIST:
@@ -256,7 +241,7 @@ uacce_scan_one(const char *dev_name)
 
 	dev->device.bus = &uacce_bus.bus;
 	dev->device.name = dev->name;
-	dev->device.devargs = uacce_devargs_lookup(dev_name);
+	dev->device.devargs = rte_bus_find_devargs(&uacce_bus.bus, dev_name);
 	snprintf(dev->name, sizeof(dev->name), "%s", dev_name);
 	snprintf(dev->dev_root, sizeof(dev->dev_root), "%s/%s",
 		 UACCE_BUS_CLASS_PATH, dev_name);
diff --git a/drivers/bus/vmbus/linux/vmbus_bus.c b/drivers/bus/vmbus/linux/vmbus_bus.c
index 4c59097273..5958b97077 100644
--- a/drivers/bus/vmbus/linux/vmbus_bus.c
+++ b/drivers/bus/vmbus/linux/vmbus_bus.c
@@ -333,7 +333,7 @@ vmbus_scan_one(const char *name)
 		dev->monitor_id = UINT8_MAX;
 	}
 
-	dev->device.devargs = vmbus_devargs_lookup(dev);
+	dev->device.devargs = rte_bus_find_devargs(&rte_vmbus_bus.bus, dev_name);
 
 	dev->device.numa_node = SOCKET_ID_ANY;
 	if (vmbus_use_numa(dev)) {
diff --git a/drivers/bus/vmbus/private.h b/drivers/bus/vmbus/private.h
index 25b8a27fcf..8ac6119ef2 100644
--- a/drivers/bus/vmbus/private.h
+++ b/drivers/bus/vmbus/private.h
@@ -98,9 +98,6 @@ struct vmbus_channel {
 
 #define VMBUS_MAX_CHANNELS	64
 
-struct rte_devargs *
-vmbus_devargs_lookup(struct rte_vmbus_device *dev);
-
 int vmbus_chan_create(const struct rte_vmbus_device *device,
 		      uint16_t relid, uint16_t subid, uint8_t monitor_id,
 		      struct vmbus_channel **new_chan);
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index f857244c85..96d16ff545 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -171,7 +171,11 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 static bool
 vmbus_ignore_device(struct rte_vmbus_device *dev)
 {
-	struct rte_devargs *devargs = vmbus_devargs_lookup(dev);
+	char name[RTE_DEV_NAME_MAX_LEN];
+	struct rte_devargs *devargs;
+
+	rte_uuid_unparse(dev->device_id, name, sizeof(name));
+	devargs = rte_bus_find_devargs(&rte_vmbus_bus.bus, name);
 
 	switch (rte_vmbus_bus.bus.conf.scan_mode) {
 	case RTE_BUS_SCAN_ALLOWLIST:
@@ -260,25 +264,16 @@ vmbus_parse(const char *name, void *addr)
 	return ret;
 }
 
-/*
- * scan for matching device args on command line
- * example:
- *	-a 'vmbus:635a7ae3-091e-4410-ad59-667c4f8c04c3,latency=20'
- */
-struct rte_devargs *
-vmbus_devargs_lookup(struct rte_vmbus_device *dev)
+static int
+vmbus_devname_compare(const char *name1, const char *name2)
 {
-	struct rte_devargs *devargs;
-	rte_uuid_t addr;
-
-	RTE_EAL_DEVARGS_FOREACH(rte_vmbus_bus.bus.name, devargs) {
-		vmbus_parse(devargs->name, &addr);
+	rte_uuid_t guid1, guid2;
 
-		if (rte_uuid_compare(dev->device_id, addr) == 0)
-			return devargs;
-	}
-	return NULL;
+	if (vmbus_parse(name1, &guid1) != 0 ||
+			vmbus_parse(name2, &guid2) != 0)
+		return 1;
 
+	return rte_uuid_compare(guid1, guid2);
 }
 
 /* register vmbus driver */
@@ -349,6 +344,7 @@ struct rte_vmbus_bus rte_vmbus_bus = {
 		.cleanup = rte_vmbus_cleanup,
 		.find_device = vmbus_find_device,
 		.parse = vmbus_parse,
+		.devname_compare = vmbus_devname_compare,
 	},
 	.device_list = TAILQ_HEAD_INITIALIZER(rte_vmbus_bus.device_list),
 	.driver_list = TAILQ_HEAD_INITIALIZER(rte_vmbus_bus.driver_list),
diff --git a/drivers/dma/idxd/idxd_bus.c b/drivers/dma/idxd/idxd_bus.c
index 9a8213bbbe..136ac511ef 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -247,16 +247,6 @@ idxd_probe_dsa(struct rte_dsa_device *dev)
 	return 0;
 }
 
-static int search_devargs(const char *name)
-{
-	struct rte_devargs *devargs;
-	RTE_EAL_DEVARGS_FOREACH(dsa_bus.bus.name, devargs) {
-		if (strcmp(devargs->name, name) == 0)
-			return 1;
-	}
-	return 0;
-}
-
 static int
 is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
 {
@@ -275,9 +265,9 @@ is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
 
 	if (retval && dsa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_UNDEFINED) {
 		if (dsa_bus.bus.conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST)
-			retval = search_devargs(dev->device.name);
+			retval = rte_bus_find_devargs(&dsa_bus.bus, dev->device.name) != NULL;
 		else
-			retval = !search_devargs(dev->device.name);
+			retval = rte_bus_find_devargs(&dsa_bus.bus, dev->device.name) == NULL;
 	}
 
 	return retval;
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 0a2311a342..863c7418bb 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -8,6 +8,7 @@
 
 #include <bus_driver.h>
 #include <rte_debug.h>
+#include <rte_devargs.h>
 #include <rte_string_fns.h>
 #include <rte_errno.h>
 
@@ -205,6 +206,25 @@ rte_bus_find_by_name(const char *busname)
 	return rte_bus_find(NULL, cmp_bus_name, (const void *)busname);
 }
 
+RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_find_devargs)
+struct rte_devargs *
+rte_bus_find_devargs(const struct rte_bus *bus, const char *name)
+{
+	rte_bus_devname_compare_t cmp = bus->devname_compare;
+	struct rte_devargs *devargs;
+
+	if (cmp == NULL)
+		cmp = strcmp;
+
+	RTE_EAL_DEVARGS_FOREACH(rte_bus_name(bus), devargs) {
+		if (cmp(name, devargs->name) != 0)
+			continue;
+		return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 bus_can_parse(const struct rte_bus *bus, const void *_name)
 {
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index 60527b75b6..430906772d 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -118,6 +118,21 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
  */
 typedef int (*rte_bus_parse_t)(const char *name, void *addr);
 
+/**
+ * Bus specific device name comparison function.
+ * Bus can normalize the names of devices using an internal representation.
+ * This helper makes it possible to check whether two names refer to the same device.
+ *
+ * @param[in] name1
+ *	device information location address,
+ * @param[in] name2
+ *	device information location address,
+ *
+ * @return
+ *      true or false
+ */
+typedef int (*rte_bus_devname_compare_t)(const char *name1, const char *name2);
+
 /**
  * Parse bus part of the device arguments.
  *
@@ -258,6 +273,7 @@ struct rte_bus {
 	rte_bus_plug_t plug;         /**< Probe single device for drivers */
 	rte_bus_unplug_t unplug;     /**< Remove single device from driver */
 	rte_bus_parse_t parse;       /**< Parse a device name */
+	rte_bus_devname_compare_t devname_compare; /**< Compare two device names */
 	rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
 	rte_dev_dma_map_t dma_map;   /**< DMA map for device in the bus */
 	rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
@@ -281,6 +297,21 @@ struct rte_bus {
 __rte_internal
 void rte_bus_register(struct rte_bus *bus);
 
+/**
+ * Find the devargs associated to a device.
+ *
+ * @param bus
+ *   A pointer to a rte_bus structure describing the bus
+ *   to be unregistered.
+ * @param dev_name
+ *   A device name.
+ *
+ * @return
+ *   Pointer to the devargs, or NULL if none found.
+ */
+__rte_internal
+struct rte_devargs *rte_bus_find_devargs(const struct rte_bus *bus, const char *name);
+
 /**
  * Helper for Bus registration.
  * The constructor has higher priority than PMD constructors.
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 6/7] bus: factorize device selection
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
                     ` (4 preceding siblings ...)
  2026-03-05 16:45   ` [RFC v3 5/7] bus: factorize devargs lookup David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 17:30     ` Bruce Richardson
  2026-03-07 20:59     ` Robin Jarry
  2026-03-05 16:45   ` [RFC v3 7/7] eal: configure initial device probing David Marchand
  2026-03-06  8:26   ` [RFC v3 0/7] Rework " David Marchand
  7 siblings, 2 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev
  Cc: Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Bruce Richardson, Kevin Laatz

All buses (thankfully) implement the same logic when it comes to
selecting the devices to probe based on -a/-b options.
As we want to adjust how devices are selected, provide a common helper
in EAL and use it in the buses.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Changes since RFC v2:
- changed API to query about a device name and hide the devargs meaning
  in the common code,

---
 drivers/bus/auxiliary/auxiliary_common.c | 19 ----------------
 drivers/bus/auxiliary/linux/auxiliary.c  |  2 +-
 drivers/bus/auxiliary/private.h          |  6 -----
 drivers/bus/cdx/cdx.c                    | 21 +-----------------
 drivers/bus/dpaa/dpaa_bus.c              | 24 ++++++--------------
 drivers/bus/fslmc/fslmc_bus.c            | 22 ++++++-------------
 drivers/bus/pci/bsd/pci.c                |  5 ++++-
 drivers/bus/pci/linux/pci.c              |  2 +-
 drivers/bus/pci/pci_common.c             | 23 -------------------
 drivers/bus/pci/private.h                | 11 ----------
 drivers/bus/pci/windows/pci.c            |  4 +++-
 drivers/bus/platform/platform.c          | 28 ++----------------------
 drivers/bus/uacce/uacce.c                | 22 +------------------
 drivers/bus/vmbus/vmbus_common.c         | 25 +--------------------
 drivers/dma/idxd/idxd_bus.c              |  8 ++-----
 lib/eal/common/eal_common_bus.c          | 19 ++++++++++++++++
 lib/eal/include/bus_driver.h             |  6 +++++
 17 files changed, 55 insertions(+), 192 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index e5b4f4460d..8f3e90eaf0 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -384,25 +384,6 @@ auxiliary_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
 	return aux_dev->driver->dma_unmap(aux_dev, addr, iova, len);
 }
 
-bool
-auxiliary_is_ignored_device(const char *name)
-{
-	struct rte_devargs *devargs = rte_bus_find_devargs(&auxiliary_bus.bus, name);
-
-	switch (auxiliary_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 static enum rte_iova_mode
 auxiliary_get_iommu_class(void)
 {
diff --git a/drivers/bus/auxiliary/linux/auxiliary.c b/drivers/bus/auxiliary/linux/auxiliary.c
index 02fc9285dc..ac9bf55efa 100644
--- a/drivers/bus/auxiliary/linux/auxiliary.c
+++ b/drivers/bus/auxiliary/linux/auxiliary.c
@@ -110,7 +110,7 @@ auxiliary_scan(void)
 		if (e->d_name[0] == '.')
 			continue;
 
-		if (auxiliary_is_ignored_device(e->d_name))
+		if (rte_bus_is_ignored_device(&auxiliary_bus.bus, e->d_name))
 			continue;
 
 		snprintf(dirname, sizeof(dirname), "%s/%s",
diff --git a/drivers/bus/auxiliary/private.h b/drivers/bus/auxiliary/private.h
index 4604f6f4a7..6e61a5f494 100644
--- a/drivers/bus/auxiliary/private.h
+++ b/drivers/bus/auxiliary/private.h
@@ -53,12 +53,6 @@ int auxiliary_scan(void);
  */
 void auxiliary_on_scan(struct rte_auxiliary_device *aux_dev);
 
-/*
- * Validate whether a device with given auxiliary device should be ignored
- * or not.
- */
-bool auxiliary_is_ignored_device(const char *name);
-
 /*
  * Add an auxiliary device to the auxiliary bus (append to auxiliary device
  * list). This function also updates the bus references of the auxiliary
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index 0801825ef5..58d8c8b4da 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -151,25 +151,6 @@ void rte_cdx_unmap_device(struct rte_cdx_device *dev)
 	cdx_vfio_unmap_resource(dev);
 }
 
-static bool
-cdx_ignore_device(const char *dev_name)
-{
-	struct rte_devargs *devargs = rte_bus_find_devargs(&rte_cdx_bus.bus, dev_name);
-
-	switch (rte_cdx_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 /*
  * Scan one cdx sysfs entry, and fill the devices list from it.
  * It checks if the CDX device is bound to vfio-cdx driver. In case
@@ -269,7 +250,7 @@ cdx_scan(void)
 		if (e->d_name[0] == '.')
 			continue;
 
-		if (cdx_ignore_device(e->d_name))
+		if (rte_bus_is_ignored_device(&rte_cdx_bus.bus, e->d_name))
 			continue;
 
 		snprintf(dirname, sizeof(dirname), "%s/%s",
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 356c56d989..9ff58af0c4 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -717,7 +717,6 @@ rte_dpaa_bus_probe(void)
 	struct rte_dpaa_driver *drv;
 	FILE *svr_file = NULL;
 	uint32_t svr_ver;
-	int probe_all = rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST;
 	static int process_once;
 	char *penv;
 
@@ -725,9 +724,6 @@ rte_dpaa_bus_probe(void)
 	if (!rte_dpaa_bus.detected)
 		return 0;
 
-	if (rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST)
-		probe_all = true;
-
 	svr_file = fopen(DPAA_SOC_ID_FILE, "r");
 	if (svr_file) {
 		if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
@@ -809,21 +805,15 @@ rte_dpaa_bus_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_BLOCKED)
+			if (rte_bus_is_ignored_device(&rte_dpaa_bus.bus, dev->name))
 				continue;
 
-			if (probe_all ||
-			    (dev->device.devargs &&
-			     dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
-				ret = drv->probe(drv, dev);
-				if (ret) {
-					DPAA_BUS_ERR("unable to probe:%s",
-						     dev->name);
-				} else {
-					dev->driver = drv;
-					dev->device.driver = &drv->driver;
-				}
+			ret = drv->probe(drv, dev);
+			if (ret) {
+				DPAA_BUS_ERR("unable to probe: %s", dev->name);
+			} else {
+				dev->driver = drv;
+				dev->device.driver = &drv->driver;
 			}
 			break;
 		}
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index f72b512b1a..b5d839b6b0 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -407,7 +407,6 @@ static int
 rte_fslmc_probe(void)
 {
 	int ret = 0;
-	int probe_all;
 
 	struct rte_dpaa2_device *dev;
 	struct rte_dpaa2_driver *drv;
@@ -454,8 +453,6 @@ rte_fslmc_probe(void)
 		return 0;
 	}
 
-	probe_all = rte_fslmc_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST;
-
 	TAILQ_FOREACH(dev, &rte_fslmc_bus.device_list, next) {
 		TAILQ_FOREACH(drv, &rte_fslmc_bus.driver_list, next) {
 			ret = rte_fslmc_match(drv, dev);
@@ -465,23 +462,18 @@ rte_fslmc_probe(void)
 			if (rte_dev_is_probed(&dev->device))
 				continue;
 
-			if (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+			if (rte_bus_is_ignored_device(&rte_fslmc_bus.bus, dev->device.name)) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blocked, skipping",
 					      dev->device.name);
 				continue;
 			}
 
-			if (probe_all ||
-			   (dev->device.devargs &&
-			    dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
-				ret = drv->probe(drv, dev);
-				if (ret) {
-					DPAA2_BUS_ERR("Unable to probe");
-				} else {
-					dev->driver = drv;
-					dev->device.driver = &drv->driver;
-				}
+			ret = drv->probe(drv, dev);
+			if (ret) {
+				DPAA2_BUS_ERR("Unable to probe");
+			} else {
+				dev->driver = drv;
+				dev->device.driver = &drv->driver;
 			}
 			break;
 		}
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index 3f13e1d6ac..ffd84ee5f0 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -370,12 +370,15 @@ rte_pci_scan(void)
 		}
 
 		for (i = 0; i < conf_io.num_matches; i++) {
+			char name[RTE_DEV_NAME_MAX_LEN];
+
 			pci_addr.domain = matches[i].pc_sel.pc_domain;
 			pci_addr.bus = matches[i].pc_sel.pc_bus;
 			pci_addr.devid = matches[i].pc_sel.pc_dev;
 			pci_addr.function = matches[i].pc_sel.pc_func;
+			rte_pci_device_name(&pci_addr, name, sizeof(name));
 
-			if (rte_pci_ignore_device(&pci_addr))
+			if (rte_bus_is_ignored_device(&rte_pci_bus.bus, name))
 				continue;
 
 			if (pci_scan_one(fd, &matches[i]) < 0)
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index 2ffac82e94..03a3c37dea 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -458,7 +458,7 @@ rte_pci_scan(void)
 		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
 			continue;
 
-		if (rte_pci_ignore_device(&addr))
+		if (rte_bus_is_ignored_device(&rte_pci_bus.bus, e->d_name))
 			continue;
 
 		snprintf(dirname, sizeof(dirname), "%s/%s",
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 8782dc342a..5ef9e80e3e 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -713,29 +713,6 @@ pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 	return -1;
 }
 
-bool
-rte_pci_ignore_device(const struct rte_pci_addr *pci_addr)
-{
-	char name[RTE_DEV_NAME_MAX_LEN];
-	struct rte_devargs *devargs;
-
-	rte_pci_device_name(pci_addr, name, sizeof(name));
-	devargs = rte_bus_find_devargs(&rte_pci_bus.bus, name);
-
-	switch (rte_pci_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 enum rte_iova_mode
 rte_pci_get_iommu_class(void)
 {
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 38109844b9..8591c4a0a7 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -82,17 +82,6 @@ pci_common_set(struct rte_pci_device *dev);
 void
 pci_free(struct rte_pci_device_internal *pdev);
 
-/**
- * Validate whether a device with given PCI address should be ignored or not.
- *
- * @param pci_addr
- *	PCI address of device to be validated
- * @return
- *	true: if device is to be ignored,
- *	false: if device is to be scanned,
- */
-bool rte_pci_ignore_device(const struct rte_pci_addr *pci_addr);
-
 /**
  * Add a PCI device to the PCI Bus (append to PCI Device list). This function
  * also updates the bus references of the PCI Device (and the generic device
diff --git a/drivers/bus/pci/windows/pci.c b/drivers/bus/pci/windows/pci.c
index a5ce3b51f7..91c8e567d1 100644
--- a/drivers/bus/pci/windows/pci.c
+++ b/drivers/bus/pci/windows/pci.c
@@ -373,6 +373,7 @@ pci_scan_one(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data)
 	struct rte_pci_device *dev = NULL;
 	int ret = -1;
 	char  pci_device_info[REGSTR_VAL_MAX_HCID_LEN];
+	char name[RTE_DEV_NAME_MAX_LEN];
 	struct rte_pci_addr addr;
 	struct rte_pci_id pci_id;
 
@@ -380,7 +381,8 @@ pci_scan_one(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data)
 	if (ret != 0)
 		goto end;
 
-	if (rte_pci_ignore_device(&addr)) {
+	rte_pci_device_name(&addr, name, sizeof(name));
+	if (rte_bus_is_ignored_device(&rte_pci_bus.bus, name)) {
 		/*
 		 * We won't add this device, but we want to continue
 		 * looking for supported devices
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 23c39aada6..ad7898f011 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -43,30 +43,6 @@ rte_platform_unregister(struct rte_platform_driver *pdrv)
 	TAILQ_REMOVE(&platform_bus.driver_list, pdrv, next);
 }
 
-static bool
-dev_allowed(const char *dev_name)
-{
-	struct rte_devargs *devargs;
-
-	devargs = rte_bus_find_devargs(&platform_bus.bus, dev_name);
-	if (devargs == NULL)
-		return true;
-
-	switch (platform_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs->policy == RTE_DEV_ALLOWED)
-			return true;
-		break;
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs->policy == RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-
-	return true;
-}
-
 static int
 dev_add(const char *dev_name)
 {
@@ -160,7 +136,7 @@ platform_bus_scan(void)
 		if (dev_name[0] == '.')
 			continue;
 
-		if (!dev_allowed(dev_name))
+		if (rte_bus_is_ignored_device(&platform_bus.bus, dev_name))
 			continue;
 
 		if (!dev_is_bound_vfio_platform(dev_name))
@@ -484,7 +460,7 @@ platform_bus_plug(struct rte_device *dev)
 {
 	struct rte_platform_device *pdev;
 
-	if (!dev_allowed(dev->name))
+	if (rte_bus_is_ignored_device(&platform_bus.bus, dev->name))
 		return -EPERM;
 
 	if (!dev_is_bound_vfio_platform(dev->name))
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 1a3deea31a..c99fdae28b 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -69,26 +69,6 @@ extern int uacce_bus_logtype;
 #define UACCE_BUS_DEBUG(fmt, ...) UACCE_BUS_LOG(DEBUG, fmt, ##__VA_ARGS__)
 
 
-static bool
-uacce_ignore_device(const char *dev_name)
-{
-	struct rte_devargs *devargs = rte_bus_find_devargs(&uacce_bus.bus, dev_name);
-
-	switch (uacce_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-
-	return true;
-}
-
 /*
  * Returns the number of bytes read (removed last newline) on success.
  * Otherwise negative value is returned.
@@ -295,7 +275,7 @@ uacce_scan(void)
 			continue;
 		}
 
-		if (uacce_ignore_device(e->d_name))
+		if (rte_bus_is_ignored_device(&uacce_bus.bus, e->d_name))
 			continue;
 
 		if (uacce_scan_one(e->d_name) < 0)
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index 96d16ff545..a9eb7cf933 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -168,29 +168,6 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	return 1;
 }
 
-static bool
-vmbus_ignore_device(struct rte_vmbus_device *dev)
-{
-	char name[RTE_DEV_NAME_MAX_LEN];
-	struct rte_devargs *devargs;
-
-	rte_uuid_unparse(dev->device_id, name, sizeof(name));
-	devargs = rte_bus_find_devargs(&rte_vmbus_bus.bus, name);
-
-	switch (rte_vmbus_bus.bus.conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
-		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
-			return false;
-		break;
-	case RTE_BUS_SCAN_UNDEFINED:
-	case RTE_BUS_SCAN_BLOCKLIST:
-		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
-			return false;
-		break;
-	}
-	return true;
-}
-
 /*
  * Scan the vmbus, and call the devinit() function for
  * all registered drivers that have a matching entry in its id_table
@@ -209,7 +186,7 @@ rte_vmbus_probe(void)
 
 		rte_uuid_unparse(dev->device_id, ubuf, sizeof(ubuf));
 
-		if (vmbus_ignore_device(dev))
+		if (rte_bus_is_ignored_device(&rte_vmbus_bus.bus, ubuf))
 			continue;
 
 		if (vmbus_probe_all_drivers(dev) < 0) {
diff --git a/drivers/dma/idxd/idxd_bus.c b/drivers/dma/idxd/idxd_bus.c
index 136ac511ef..00e7e7315c 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -263,12 +263,8 @@ is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
 	if (strncmp(name, prefix, prefixlen) == 0 && name[prefixlen] == '_')
 		retval = 1;
 
-	if (retval && dsa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_UNDEFINED) {
-		if (dsa_bus.bus.conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST)
-			retval = rte_bus_find_devargs(&dsa_bus.bus, dev->device.name) != NULL;
-		else
-			retval = rte_bus_find_devargs(&dsa_bus.bus, dev->device.name) == NULL;
-	}
+	if (retval && !rte_bus_is_ignored_device(&dsa_bus.bus, dev->device.name))
+		retval = 1;
 
 	return retval;
 }
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 863c7418bb..2ca0af7914 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -246,6 +246,25 @@ rte_bus_find_by_device_name(const char *str)
 	return rte_bus_find(NULL, bus_can_parse, name);
 }
 
+RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_is_ignored_device)
+bool
+rte_bus_is_ignored_device(const struct rte_bus *bus, const char *dev_name)
+{
+	struct rte_devargs *devargs = rte_bus_find_devargs(bus, dev_name);
+
+	switch (bus->conf.scan_mode) {
+	case RTE_BUS_SCAN_ALLOWLIST:
+		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
+			return false;
+		break;
+	case RTE_BUS_SCAN_UNDEFINED:
+	case RTE_BUS_SCAN_BLOCKLIST:
+		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
+			return false;
+		break;
+	}
+	return true;
+}
 
 /*
  * Get iommu class of devices on the bus.
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index 430906772d..dc30e06843 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -312,6 +312,12 @@ void rte_bus_register(struct rte_bus *bus);
 __rte_internal
 struct rte_devargs *rte_bus_find_devargs(const struct rte_bus *bus, const char *name);
 
+/**
+ * Indicate if a device should be skipped during probing of a bus.
+ */
+__rte_internal
+bool rte_bus_is_ignored_device(const struct rte_bus *bus, const char *dev_name);
+
 /**
  * Helper for Bus registration.
  * The constructor has higher priority than PMD constructors.
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [RFC v3 7/7] eal: configure initial device probing
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
                     ` (5 preceding siblings ...)
  2026-03-05 16:45   ` [RFC v3 6/7] bus: factorize device selection David Marchand
@ 2026-03-05 16:45   ` David Marchand
  2026-03-05 17:33     ` Bruce Richardson
  2026-03-07 21:05     ` Robin Jarry
  2026-03-06  8:26   ` [RFC v3 0/7] Rework " David Marchand
  7 siblings, 2 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 16:45 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Andrew Rybchenko

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 which can be summed up as disabling
automatic probing.
In case some applications want to require automatic probing, add the
opposite option.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Changes since RFC v2:
- added -A short option alias as it seems intuitive to use with -a,
- renamed option to --no-auto-probing (half Robin and half Thomas
  suggestions),
- made -A and -b conflicting options,
- added opposite option in case an application wants an explicit behavior,
- updated unit tests accordingly,
- updated documentation (namely some detail on --vdev),

Changes since RFC v1:
- changed approach following Bruce suggestion,

---
 app/test/test_eal_flags.c                 | 63 +++++++++++++++++++++++
 devtools/test-null.sh                     |  2 +-
 doc/guides/linux_gsg/eal_args.include.rst | 13 +++++
 lib/eal/common/eal_common_bus.c           | 17 +++---
 lib/eal/common/eal_common_options.c       | 10 ++++
 lib/eal/common/eal_internal_cfg.h         |  1 +
 lib/eal/common/eal_option_list.h          |  2 +
 7 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index b3a8d0ae6f..0fa0e1997e 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -119,6 +119,8 @@ test_misc_flags(void)
 #define no_hpet "--no-hpet"
 #define no_huge "--no-huge"
 #define no_shconf "--no-shconf"
+#define auto_probing "--auto-probing"
+#define no_auto_probing "--no-auto-probing"
 #define allow "--allow"
 #define vdev "--vdev"
 #define no_pci "--no-pci"
@@ -338,6 +340,14 @@ test_allow_flag(void)
 			allow, "09:0B.3,type=test",
 			allow, "08:00.1,type=normal",
 	};
+	const char *wlval4[] = {prgname, prefix, mp_flag, eal_debug_logs,
+			no_auto_probing };
+	const char *wlval5[] = {prgname, prefix, mp_flag, eal_debug_logs,
+			no_auto_probing, allow, "00FF:09:0B.3"};
+	const char *wlval6[] = {prgname, prefix, mp_flag, eal_debug_logs,
+			auto_probing };
+	const char *wlval7[] = {prgname, prefix, mp_flag, eal_debug_logs,
+			auto_probing, allow, "00FF:09:0B.3"};
 
 	for (i = 0; i < RTE_DIM(wlinval); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
@@ -360,6 +370,26 @@ test_allow_flag(void)
 			__LINE__);
 		return -1;
 	}
+	if (launch_proc(wlval4) != 0 ) {
+		printf("Error (line %d) - process did not run ok with no-auto-probing\n",
+			__LINE__);
+		return -1;
+	}
+	if (launch_proc(wlval5) != 0 ) {
+		printf("Error (line %d) - process did not run ok with no-auto-probing + allow\n",
+			__LINE__);
+		return -1;
+	}
+	if (launch_proc(wlval6) != 0 ) {
+		printf("Error (line %d) - process did not run ok with auto-probing\n",
+			__LINE__);
+		return -1;
+	}
+	if (launch_proc(wlval7) != 0 ) {
+		printf("Error (line %d) - process did not run ok with auto-probing + allow\n",
+			__LINE__);
+		return -1;
+	}
 
 	return 0;
 }
@@ -383,6 +413,11 @@ test_invalid_b_flag(void)
 		{prgname, prefix, mp_flag, eal_debug_logs, "-b", "error0:0:0.1"},
 		{prgname, prefix, mp_flag, eal_debug_logs, "-b", "0:0:0.1.2"},
 	};
+	const char *blinval_probing[] =
+		{prgname, prefix, mp_flag, eal_debug_logs, "-b", "0:0.0", auto_probing};
+	const char *blinval_probing_inval[] =
+		{prgname, prefix, mp_flag, eal_debug_logs, "-b", "0:0.0", no_auto_probing};
+
 	/* Test with valid blocklist option */
 	const char *blval[] = {prgname, prefix, mp_flag, eal_debug_logs,
 			       "-b", "FF:09:0B.3"};
@@ -396,6 +431,16 @@ test_invalid_b_flag(void)
 			return -1;
 		}
 	}
+	if (launch_proc(blinval_probing) != 0) {
+		printf("Error (line %d) - process did not run ok with blocklist and auto-probing\n",
+			__LINE__);
+		return -1;
+	}
+	if (launch_proc(blinval_probing_inval) == 0) {
+		printf("Error (line %d) - process did run ok with blocklist and no-auto-probing\n",
+			__LINE__);
+		return -1;
+	}
 	if (launch_proc(blval) != 0) {
 		printf("Error (line %d) - process did not run ok with valid blocklist value\n",
 			__LINE__);
@@ -434,6 +479,12 @@ test_invalid_vdev_flag(void)
 	const char *vdevval3[] = {prgname, prefix, no_huge, eal_debug_logs,
 				bus_debug_logs, no_pci, vdev, "net_ring0,nodeaction=r1:0:CREATE"};
 
+	const char *vdevval4[] = {prgname, prefix, no_huge, eal_debug_logs,
+				bus_debug_logs, no_auto_probing, vdev, "net_ring0"};
+
+	const char *vdevval5[] = {prgname, prefix, no_huge, eal_debug_logs,
+				bus_debug_logs, auto_probing, vdev, "net_ring0"};
+
 	if (launch_proc(vdevinval) == 0) {
 		printf("Error (line %d) - process did run ok with invalid vdev parameter\n",
 			__LINE__);
@@ -457,6 +508,18 @@ test_invalid_vdev_flag(void)
 			__LINE__);
 		return -1;
 	}
+
+	if (launch_proc(vdevval4) != 0) {
+		printf("Error (line %d) - process did not run ok with valid vdev value and no-auto-probing\n",
+			__LINE__);
+		return -1;
+	}
+
+	if (launch_proc(vdevval5) != 0) {
+		printf("Error (line %d) - process did not run ok with valid vdev value and auto-probing\n",
+			__LINE__);
+		return -1;
+	}
 	return 0;
 #else
 	return TEST_SKIPPED;
diff --git a/devtools/test-null.sh b/devtools/test-null.sh
index 8f21189262..5e8a1b20cd 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 -A --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..db9eff9321 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -101,6 +101,19 @@ Lcore-related options
 Device-related options
 ~~~~~~~~~~~~~~~~~~~~~~
 
+*   ``-A, --no-auto-probing``
+
+    By default, EAL probes all devices on every available bus, unless some ``-a``/``-b``
+    options are passed.
+    Disable automatic probing of non-blocked devices.
+
+.. Note::
+    Block list cannot be used when auto probing is disabled.
+
+    On the other hand, disabling auto probing does not affect the VDEV bus.
+    The VDEV bus is not concerned by automatic probing and requires explicit
+    ``-a`` or ``--vdev``.
+
 *   ``-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 2ca0af7914..47ba303468 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -250,18 +250,23 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_is_ignored_device)
 bool
 rte_bus_is_ignored_device(const struct rte_bus *bus, const char *dev_name)
 {
+	const struct internal_config *internal_conf = eal_get_internal_configuration();
 	struct rte_devargs *devargs = rte_bus_find_devargs(bus, dev_name);
+	enum rte_bus_scan_mode scan_mode = bus->conf.scan_mode;
 
-	switch (bus->conf.scan_mode) {
-	case RTE_BUS_SCAN_ALLOWLIST:
+	if (scan_mode == RTE_BUS_SCAN_UNDEFINED) {
+		if (internal_conf->no_auto_probing != 0)
+			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..290386dc63 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -233,10 +233,15 @@ eal_collate_args(int argc, char **argv)
 		EAL_LOG(ERR, "Options allow (-a) and block (-b) can't be used at the same time");
 		return -1;
 	}
+	if (args.no_auto_probing && !TAILQ_EMPTY(&args.block)) {
+		EAL_LOG(ERR, "Options no-auto-probing and block (-b) can't be used at the same time");
+		return -1;
+	}
 
 	/* for non-list args, we can just check for zero/null values using macro */
 	if (CONFLICTING_OPTIONS(args, coremask, lcores) ||
 			CONFLICTING_OPTIONS(args, service_coremask, service_corelist) ||
+			CONFLICTING_OPTIONS(args, no_auto_probing, auto_probing) ||
 			CONFLICTING_OPTIONS(args, no_telemetry, telemetry) ||
 			CONFLICTING_OPTIONS(args, memory_size, numa_mem) ||
 			CONFLICTING_OPTIONS(args, no_huge, numa_mem) ||
@@ -518,6 +523,8 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
 	memset(internal_cfg->vfio_vf_token, 0,
 			sizeof(internal_cfg->vfio_vf_token));
 
+	internal_cfg->no_auto_probing = 0;
+
 #ifdef RTE_LIBEAL_USE_HPET
 	internal_cfg->no_hpet = 0;
 #else
@@ -1972,6 +1979,9 @@ eal_parse_args(void)
 		}
 	}
 
+	if (args.no_auto_probing)
+		int_cfg->no_auto_probing = 1;
+
 	/* 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_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h
index 95d327a613..fac45cbe66 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -104,6 +104,7 @@ struct internal_config {
 	struct simd_bitwidth max_simd_bitwidth;
 	/**< max simd bitwidth path to use */
 	size_t huge_worker_stack_size; /**< worker thread stack size */
+	unsigned int no_auto_probing; /**< true to switch from block-listing to allow-listing */
 };
 
 void eal_reset_internal_config(struct internal_config *internal_cfg);
diff --git a/lib/eal/common/eal_option_list.h b/lib/eal/common/eal_option_list.h
index abee16340b..6a5ddfd8d1 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("--auto-probing", NULL, "Let EAL probe all available devices unless some -a/-b option is set.", auto_probing)
 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)
@@ -51,6 +52,7 @@ STR_ARG("--mbuf-pool-ops-name", NULL, "User defined mbuf default pool ops name",
 STR_ARG("--memory-channels", "-n", "Number of memory channels per socket", memory_channels)
 STR_ARG("--memory-ranks", "-r", "Force number of memory ranks (don't detect)", memory_ranks)
 STR_ARG("--memory-size", "-m", "Total size of memory to allocate initially", memory_size)
+BOOL_ARG("--no-auto-probing", "-A", "Do not probe any devices unless some -a option is set", no_auto_probing)
 BOOL_ARG("--no-hpet", NULL, "Disable HPET timer", no_hpet)
 BOOL_ARG("--no-huge", NULL, "Disable hugetlbfs support", no_huge)
 BOOL_ARG("--no-pci", NULL, "Disable all PCI devices", no_pci)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan
  2026-03-05 16:45   ` [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan David Marchand
@ 2026-03-05 16:56     ` Bruce Richardson
  0 siblings, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-03-05 16:56 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Rosen Xu, Chenbo Xia,
	Tomasz Duszynski, Chengwen Feng, Long Li, Wei Hu

On Thu, Mar 05, 2026 at 05:45:46PM +0100, David Marchand wrote:
> Don't hardcode the bus names in the RTE_EAL_DEVARGS_FOREACH() calls.
> The bus name is set by code in EAL.
> Even if there is nothing broken, let's reuse the name from the bus object.
> 
> And remove the now useless macros.
> 
> Note: in the ifpga bus case, the call was using an incorrect macro
> (IFPGA_ARG_NAME instead of IFPGA_BUS_NAME), yet it was working fine
> as this macro is aligned with the ifpga bus name.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 5/7] bus: factorize devargs lookup
  2026-03-05 16:45   ` [RFC v3 5/7] bus: factorize devargs lookup David Marchand
@ 2026-03-05 17:06     ` Bruce Richardson
  2026-03-05 17:10       ` David Marchand
  0 siblings, 1 reply; 40+ messages in thread
From: Bruce Richardson @ 2026-03-05 17:06 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Thu, Mar 05, 2026 at 05:45:47PM +0100, David Marchand wrote:
> Each bus reimplements some similar devargs lookup code.
> 
> The differences are in how some bus (PCI, VMBUS etc...) normalizes the
> device names. We can't use the .parse existing handler from outside the
> bus code itself, as the size of the bus specific device location address
> is unknown.
> Introduce a bus specific helper to compare two device names and
> hide this ugly detail.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---

Looks generally good. Couple of minor naming suggestions inline below.

Acked-by: Bruce Richardson <bruce.richardson@intel.com>


>  drivers/bus/auxiliary/auxiliary_common.c | 16 ++-------
>  drivers/bus/cdx/cdx.c                    | 14 +-------
>  drivers/bus/dpaa/dpaa_bus.c              | 41 +++++++++++++-----------
>  drivers/bus/fslmc/fslmc_bus.c            | 34 ++++++++++----------
>  drivers/bus/pci/pci_common.c             | 38 +++++++++++-----------
>  drivers/bus/platform/platform.c          | 17 ++--------
>  drivers/bus/uacce/uacce.c                | 19 ++---------
>  drivers/bus/vmbus/linux/vmbus_bus.c      |  2 +-
>  drivers/bus/vmbus/private.h              |  3 --
>  drivers/bus/vmbus/vmbus_common.c         | 30 ++++++++---------
>  drivers/dma/idxd/idxd_bus.c              | 14 ++------
>  lib/eal/common/eal_common_bus.c          | 20 ++++++++++++
>  lib/eal/include/bus_driver.h             | 31 ++++++++++++++++++
>  13 files changed, 132 insertions(+), 147 deletions(-)
> 

<snip>

> diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
> index 0a2311a342..863c7418bb 100644
> --- a/lib/eal/common/eal_common_bus.c
> +++ b/lib/eal/common/eal_common_bus.c
> @@ -8,6 +8,7 @@
>  
>  #include <bus_driver.h>
>  #include <rte_debug.h>
> +#include <rte_devargs.h>
>  #include <rte_string_fns.h>
>  #include <rte_errno.h>
>  
> @@ -205,6 +206,25 @@ rte_bus_find_by_name(const char *busname)
>  	return rte_bus_find(NULL, cmp_bus_name, (const void *)busname);
>  }
>  
> +RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_find_devargs)
> +struct rte_devargs *
> +rte_bus_find_devargs(const struct rte_bus *bus, const char *name)
> +{
> +	rte_bus_devname_compare_t cmp = bus->devname_compare;
> +	struct rte_devargs *devargs;
> +
> +	if (cmp == NULL)
> +		cmp = strcmp;
> +
> +	RTE_EAL_DEVARGS_FOREACH(rte_bus_name(bus), devargs) {
> +		if (cmp(name, devargs->name) != 0)
> +			continue;
> +		return devargs;
> +	}
> +
> +	return NULL;
> +}
> +
>  static int
>  bus_can_parse(const struct rte_bus *bus, const void *_name)
>  {
> diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
> index 60527b75b6..430906772d 100644
> --- a/lib/eal/include/bus_driver.h
> +++ b/lib/eal/include/bus_driver.h
> @@ -118,6 +118,21 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
>   */
>  typedef int (*rte_bus_parse_t)(const char *name, void *addr);
>  
> +/**
> + * Bus specific device name comparison function.
> + * Bus can normalize the names of devices using an internal representation.
> + * This helper makes it possible to check whether two names refer to the same device.
> + *
> + * @param[in] name1
> + *	device information location address,
> + * @param[in] name2
> + *	device information location address,
> + *
> + * @return
> + *      true or false
> + */
> +typedef int (*rte_bus_devname_compare_t)(const char *name1, const char *name2);
> +

This is a good addition.

>  /**
>   * Parse bus part of the device arguments.
>   *
> @@ -258,6 +273,7 @@ struct rte_bus {
>  	rte_bus_plug_t plug;         /**< Probe single device for drivers */
>  	rte_bus_unplug_t unplug;     /**< Remove single device from driver */
>  	rte_bus_parse_t parse;       /**< Parse a device name */
> +	rte_bus_devname_compare_t devname_compare; /**< Compare two device names */
>  	rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
>  	rte_dev_dma_map_t dma_map;   /**< DMA map for device in the bus */
>  	rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
> @@ -281,6 +297,21 @@ struct rte_bus {
>  __rte_internal
>  void rte_bus_register(struct rte_bus *bus);
>  
> +/**
> + * Find the devargs associated to a device.
> + *
> + * @param bus
> + *   A pointer to a rte_bus structure describing the bus
> + *   to be unregistered.
> + * @param dev_name
> + *   A device name.
> + *
> + * @return
> + *   Pointer to the devargs, or NULL if none found.
> + */
> +__rte_internal
> +struct rte_devargs *rte_bus_find_devargs(const struct rte_bus *bus, const char *name);
> +

The doxygen says the parameter is dev_name, while the prototype only uses
name. I'd prefer this to be "dev_name". [I nearly one if the function
itself should have an extra "_" and be "find_dev_args", as it's finding
the args for a particular device, rather than finding the "devargs" for the
bus itself.]

>  /**
>   * Helper for Bus registration.
>   * The constructor has higher priority than PMD constructors.
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 5/7] bus: factorize devargs lookup
  2026-03-05 17:06     ` Bruce Richardson
@ 2026-03-05 17:10       ` David Marchand
  0 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-05 17:10 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Thu, 5 Mar 2026 at 18:06, Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Thu, Mar 05, 2026 at 05:45:47PM +0100, David Marchand wrote:
> > Each bus reimplements some similar devargs lookup code.
> >
> > The differences are in how some bus (PCI, VMBUS etc...) normalizes the
> > device names. We can't use the .parse existing handler from outside the
> > bus code itself, as the size of the bus specific device location address
> > is unknown.
> > Introduce a bus specific helper to compare two device names and
> > hide this ugly detail.
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
>
> Looks generally good. Couple of minor naming suggestions inline below.
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
>
>
> >  drivers/bus/auxiliary/auxiliary_common.c | 16 ++-------
> >  drivers/bus/cdx/cdx.c                    | 14 +-------
> >  drivers/bus/dpaa/dpaa_bus.c              | 41 +++++++++++++-----------
> >  drivers/bus/fslmc/fslmc_bus.c            | 34 ++++++++++----------
> >  drivers/bus/pci/pci_common.c             | 38 +++++++++++-----------
> >  drivers/bus/platform/platform.c          | 17 ++--------
> >  drivers/bus/uacce/uacce.c                | 19 ++---------
> >  drivers/bus/vmbus/linux/vmbus_bus.c      |  2 +-
> >  drivers/bus/vmbus/private.h              |  3 --
> >  drivers/bus/vmbus/vmbus_common.c         | 30 ++++++++---------
> >  drivers/dma/idxd/idxd_bus.c              | 14 ++------
> >  lib/eal/common/eal_common_bus.c          | 20 ++++++++++++
> >  lib/eal/include/bus_driver.h             | 31 ++++++++++++++++++
> >  13 files changed, 132 insertions(+), 147 deletions(-)
> >
>
> <snip>
>
> > diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
> > index 0a2311a342..863c7418bb 100644
> > --- a/lib/eal/common/eal_common_bus.c
> > +++ b/lib/eal/common/eal_common_bus.c
> > @@ -8,6 +8,7 @@
> >
> >  #include <bus_driver.h>
> >  #include <rte_debug.h>
> > +#include <rte_devargs.h>
> >  #include <rte_string_fns.h>
> >  #include <rte_errno.h>
> >
> > @@ -205,6 +206,25 @@ rte_bus_find_by_name(const char *busname)
> >       return rte_bus_find(NULL, cmp_bus_name, (const void *)busname);
> >  }
> >
> > +RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_find_devargs)
> > +struct rte_devargs *
> > +rte_bus_find_devargs(const struct rte_bus *bus, const char *name)
> > +{
> > +     rte_bus_devname_compare_t cmp = bus->devname_compare;
> > +     struct rte_devargs *devargs;
> > +
> > +     if (cmp == NULL)
> > +             cmp = strcmp;
> > +
> > +     RTE_EAL_DEVARGS_FOREACH(rte_bus_name(bus), devargs) {
> > +             if (cmp(name, devargs->name) != 0)
> > +                     continue;
> > +             return devargs;
> > +     }
> > +
> > +     return NULL;
> > +}
> > +
> >  static int
> >  bus_can_parse(const struct rte_bus *bus, const void *_name)
> >  {
> > diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
> > index 60527b75b6..430906772d 100644
> > --- a/lib/eal/include/bus_driver.h
> > +++ b/lib/eal/include/bus_driver.h
> > @@ -118,6 +118,21 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
> >   */
> >  typedef int (*rte_bus_parse_t)(const char *name, void *addr);
> >
> > +/**
> > + * Bus specific device name comparison function.
> > + * Bus can normalize the names of devices using an internal representation.
> > + * This helper makes it possible to check whether two names refer to the same device.
> > + *
> > + * @param[in] name1
> > + *   device information location address,
> > + * @param[in] name2
> > + *   device information location address,
> > + *
> > + * @return
> > + *      true or false
> > + */
> > +typedef int (*rte_bus_devname_compare_t)(const char *name1, const char *name2);
> > +
>
> This is a good addition.
>
> >  /**
> >   * Parse bus part of the device arguments.
> >   *
> > @@ -258,6 +273,7 @@ struct rte_bus {
> >       rte_bus_plug_t plug;         /**< Probe single device for drivers */
> >       rte_bus_unplug_t unplug;     /**< Remove single device from driver */
> >       rte_bus_parse_t parse;       /**< Parse a device name */
> > +     rte_bus_devname_compare_t devname_compare; /**< Compare two device names */
> >       rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
> >       rte_dev_dma_map_t dma_map;   /**< DMA map for device in the bus */
> >       rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
> > @@ -281,6 +297,21 @@ struct rte_bus {
> >  __rte_internal
> >  void rte_bus_register(struct rte_bus *bus);
> >
> > +/**
> > + * Find the devargs associated to a device.
> > + *
> > + * @param bus
> > + *   A pointer to a rte_bus structure describing the bus
> > + *   to be unregistered.
> > + * @param dev_name
> > + *   A device name.
> > + *
> > + * @return
> > + *   Pointer to the devargs, or NULL if none found.
> > + */
> > +__rte_internal
> > +struct rte_devargs *rte_bus_find_devargs(const struct rte_bus *bus, const char *name);
> > +
>
> The doxygen says the parameter is dev_name, while the prototype only uses
> name. I'd prefer this to be "dev_name". [I nearly one if the function
> itself should have an extra "_" and be "find_dev_args", as it's finding
> the args for a particular device, rather than finding the "devargs" for the
> bus itself.]

Good catch.

Err well, on doxygen / prototype misalignment.. documentation
generation should fail if it is not aligned.
Strange I did not see this.
Ah.. it is a driver header, so we probably don't generate any doc for this.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 6/7] bus: factorize device selection
  2026-03-05 16:45   ` [RFC v3 6/7] bus: factorize device selection David Marchand
@ 2026-03-05 17:30     ` Bruce Richardson
  2026-03-09  9:50       ` David Marchand
  2026-03-07 20:59     ` Robin Jarry
  1 sibling, 1 reply; 40+ messages in thread
From: Bruce Richardson @ 2026-03-05 17:30 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz

On Thu, Mar 05, 2026 at 05:45:48PM +0100, David Marchand wrote:
> All buses (thankfully) implement the same logic when it comes to
> selecting the devices to probe based on -a/-b options.
> As we want to adjust how devices are selected, provide a common helper
> in EAL and use it in the buses.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---

Acked-by: Bruce Richardson <bruce.richardson@intel.com>

I was going to suggest that we avoid having a per-bus scan mode, but then I
realised after looking that the final patch in this series that that won't
work for vdev bus which can't use auto-probing.

> Changes since RFC v2:
> - changed API to query about a device name and hide the devargs meaning
>   in the common code,
>
<snip> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 7/7] eal: configure initial device probing
  2026-03-05 16:45   ` [RFC v3 7/7] eal: configure initial device probing David Marchand
@ 2026-03-05 17:33     ` Bruce Richardson
  2026-03-07 21:05     ` Robin Jarry
  1 sibling, 0 replies; 40+ messages in thread
From: Bruce Richardson @ 2026-03-05 17:33 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, Thomas Monjalon, Andrew Rybchenko

On Thu, Mar 05, 2026 at 05:45:49PM +0100, David Marchand wrote:
> 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 which can be summed up as disabling
> automatic probing.
> In case some applications want to require automatic probing, add the
> opposite option.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> Changes since RFC v2:
> - added -A short option alias as it seems intuitive to use with -a,
> - renamed option to --no-auto-probing (half Robin and half Thomas
>   suggestions),
> - made -A and -b conflicting options,
> - added opposite option in case an application wants an explicit behavior,
> - updated unit tests accordingly,
> - updated documentation (namely some detail on --vdev),
> 
> Changes since RFC v1:
> - changed approach following Bruce suggestion,
> 
> ---
>  app/test/test_eal_flags.c                 | 63 +++++++++++++++++++++++
>  devtools/test-null.sh                     |  2 +-
>  doc/guides/linux_gsg/eal_args.include.rst | 13 +++++
>  lib/eal/common/eal_common_bus.c           | 17 +++---
>  lib/eal/common/eal_common_options.c       | 10 ++++
>  lib/eal/common/eal_internal_cfg.h         |  1 +
>  lib/eal/common/eal_option_list.h          |  2 +
>  7 files changed, 101 insertions(+), 7 deletions(-)
> 

While I really like "-A" as a logical shortcut, I am a little concerned it
doesn't seem a shortcut for "--no-auto-probing". However, I don't have a
better suggestion so.

Acked-by: Bruce Richardson <bruce.richardson@intel.com>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 0/7] Rework device probing
  2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
                     ` (6 preceding siblings ...)
  2026-03-05 16:45   ` [RFC v3 7/7] eal: configure initial device probing David Marchand
@ 2026-03-06  8:26   ` David Marchand
  7 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-06  8:26 UTC (permalink / raw)
  To: dev

On Thu, 5 Mar 2026 at 17:46, David Marchand <david.marchand@redhat.com> wrote:
>
> Applications relying on device hotplug don't work well with the default
> probing of all available resources.
> This series proposes to change this behavior via a new EAL option.
>
>
> --
> David Marchand
>
> Changes since RFC v2:
> - went one step further and reworked devargs lookup in buses following
>   Bruce comment (see patch 4 which is cosmetic, and patch 5),
> - updated device selection helper accordingly and
>   changed API to be device name based,
> - renamed option, added check on -b presence, updated doc in the last
>   patch,
>
> Changes since RFC v1:
> - reviewed bus probe() and cleaned up NXP drivers,
> - changed approach following Bruce comment,
>
> David Marchand (7):
>   devtools: check packet forwarding in null test
>   bus/fslmc: fix bus cleanup
>   drivers/bus: require probe function for NXP drivers
>   drivers: cleanup devargs lookup in bus scan
>   bus: factorize devargs lookup
>   bus: factorize device selection
>   eal: configure initial device probing
>
>  app/test/test_eal_flags.c                    | 63 +++++++++++++++++
>  devtools/test-null.sh                        | 10 ++-
>  doc/guides/linux_gsg/eal_args.include.rst    | 13 ++++
>  drivers/bus/auxiliary/auxiliary_common.c     | 33 +--------
>  drivers/bus/auxiliary/bus_auxiliary_driver.h |  2 -
>  drivers/bus/auxiliary/linux/auxiliary.c      |  2 +-
>  drivers/bus/auxiliary/private.h              |  6 --
>  drivers/bus/cdx/cdx.c                        | 34 +---------
>  drivers/bus/dpaa/dpaa_bus.c                  | 71 +++++++++-----------
>  drivers/bus/fslmc/fslmc_bus.c                | 69 ++++++++-----------
>  drivers/bus/fslmc/fslmc_vfio.c               | 22 ++----
>  drivers/bus/ifpga/bus_ifpga_driver.h         |  2 -
>  drivers/bus/ifpga/ifpga_bus.c                |  4 +-
>  drivers/bus/pci/bsd/pci.c                    |  5 +-
>  drivers/bus/pci/linux/pci.c                  |  2 +-
>  drivers/bus/pci/pci_common.c                 | 51 ++++----------
>  drivers/bus/pci/private.h                    | 11 ---
>  drivers/bus/pci/windows/pci.c                |  4 +-
>  drivers/bus/platform/platform.c              | 43 +-----------
>  drivers/bus/uacce/uacce.c                    | 39 +----------
>  drivers/bus/vdev/vdev.c                      |  2 +-
>  drivers/bus/vmbus/linux/vmbus_bus.c          |  2 +-
>  drivers/bus/vmbus/private.h                  |  3 -
>  drivers/bus/vmbus/vmbus_common.c             | 45 +++----------
>  drivers/dma/idxd/idxd_bus.c                  | 18 +----
>  drivers/raw/ifpga/ifpga_rawdev.c             |  2 +-
>  lib/eal/common/eal_common_bus.c              | 44 ++++++++++++
>  lib/eal/common/eal_common_options.c          | 10 +++
>  lib/eal/common/eal_internal_cfg.h            |  1 +
>  lib/eal/common/eal_option_list.h             |  2 +
>  lib/eal/include/bus_driver.h                 | 37 ++++++++++
>  31 files changed, 288 insertions(+), 364 deletions(-)

Recheck-request: github-robot


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 6/7] bus: factorize device selection
  2026-03-05 16:45   ` [RFC v3 6/7] bus: factorize device selection David Marchand
  2026-03-05 17:30     ` Bruce Richardson
@ 2026-03-07 20:59     ` Robin Jarry
  1 sibling, 0 replies; 40+ messages in thread
From: Robin Jarry @ 2026-03-07 20:59 UTC (permalink / raw)
  To: David Marchand, dev
  Cc: Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Bruce Richardson, Kevin Laatz

David Marchand, Mar 05, 2026 at 17:45:
> All buses (thankfully) implement the same logic when it comes to
> selecting the devices to probe based on -a/-b options.
> As we want to adjust how devices are selected, provide a common helper
> in EAL and use it in the buses.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> Changes since RFC v2:
> - changed API to query about a device name and hide the devargs meaning
>   in the common code,

Nice cleanup.

Reviewed-by: Robin Jarry <rjarry@redhat.com>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 7/7] eal: configure initial device probing
  2026-03-05 16:45   ` [RFC v3 7/7] eal: configure initial device probing David Marchand
  2026-03-05 17:33     ` Bruce Richardson
@ 2026-03-07 21:05     ` Robin Jarry
  1 sibling, 0 replies; 40+ messages in thread
From: Robin Jarry @ 2026-03-07 21:05 UTC (permalink / raw)
  To: David Marchand, dev; +Cc: Thomas Monjalon, Andrew Rybchenko

David Marchand, Mar 05, 2026 at 17:45:
> 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 which can be summed up as disabling
> automatic probing.
> In case some applications want to require automatic probing, add the
> opposite option.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> Changes since RFC v2:
> - added -A short option alias as it seems intuitive to use with -a,
> - renamed option to --no-auto-probing (half Robin and half Thomas
>   suggestions),
> - made -A and -b conflicting options,
> - added opposite option in case an application wants an explicit behavior,
> - updated unit tests accordingly,
> - updated documentation (namely some detail on --vdev),
>
> Changes since RFC v1:
> - changed approach following Bruce suggestion,
>
> ---

Hey David,

thanks, LGTM.

Reviewed-by: Robin Jarry <rjarry@redhat.com>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC v3 6/7] bus: factorize device selection
  2026-03-05 17:30     ` Bruce Richardson
@ 2026-03-09  9:50       ` David Marchand
  0 siblings, 0 replies; 40+ messages in thread
From: David Marchand @ 2026-03-09  9:50 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, Parav Pandit, Xueming Li, Nipun Gupta, Nikhil Agarwal,
	Hemant Agrawal, Sachin Saxena, Chenbo Xia, Tomasz Duszynski,
	Chengwen Feng, Long Li, Wei Hu, Kevin Laatz, Gaetan Rivet,
	Thomas Monjalon

Hello Bruce,

On Thu, 5 Mar 2026 at 18:30, Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Thu, Mar 05, 2026 at 05:45:48PM +0100, David Marchand wrote:
> > All buses (thankfully) implement the same logic when it comes to
> > selecting the devices to probe based on -a/-b options.
> > As we want to adjust how devices are selected, provide a common helper
> > in EAL and use it in the buses.
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
>
> I was going to suggest that we avoid having a per-bus scan mode, but then I
> realised after looking that the final patch in this series that that won't
> work for vdev bus which can't use auto-probing.

I also think we don't need the per-bus mode.
I don't understand why it was added in the first place.

The vdev bus does not consider the bus scan mode, so the current
behavior would not be broken if we removed it.

From a user pov (even before this series), -a/-b are mutually
exclusive and --vdev lives in parallel.

I'll see if it is as easy as I think and I have a try for the non RFC
series for 26.07.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2026-03-09  9:50 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-25 11:29 [RFC 1/2] devtools: check packet forwarding in null test David Marchand
2026-02-25 11:29 ` [RFC 2/2] eal: configure initial device probing David Marchand
2026-02-25 12:09   ` Bruce Richardson
2026-02-25 17:53     ` David Marchand
2026-02-26 16:20 ` [RFC v2 0/5] Rework " David Marchand
2026-02-26 16:20   ` [RFC v2 1/5] devtools: check packet forwarding in null test David Marchand
2026-02-26 16:35     ` Bruce Richardson
2026-02-26 16:20   ` [RFC v2 2/5] bus/fslmc: fix bus cleanup David Marchand
2026-02-26 16:20   ` [RFC v2 3/5] drivers/bus: require probe function for NXP drivers David Marchand
2026-02-26 16:24     ` Bruce Richardson
2026-02-26 16:20   ` [RFC v2 4/5] bus: factorize device selection David Marchand
2026-02-26 16:31     ` Bruce Richardson
2026-02-27 14:17       ` David Marchand
2026-02-27 14:33         ` Bruce Richardson
2026-02-26 16:20   ` [RFC v2 5/5] eal: configure initial device probing David Marchand
2026-02-26 16:34     ` Bruce Richardson
2026-02-26 16:50     ` Robin Jarry
2026-02-27 13:43       ` Thomas Monjalon
2026-02-27 13:51         ` Bruce Richardson
2026-02-27 22:10           ` Stephen Hemminger
2026-03-02  9:02             ` Bruce Richardson
2026-03-02 11:08               ` Morten Brørup
2026-03-02 11:13               ` David Marchand
2026-03-05 16:45 ` [RFC v3 0/7] Rework " David Marchand
2026-03-05 16:45   ` [RFC v3 1/7] devtools: check packet forwarding in null test David Marchand
2026-03-05 16:45   ` [RFC v3 2/7] bus/fslmc: fix bus cleanup David Marchand
2026-03-05 16:45   ` [RFC v3 3/7] drivers/bus: require probe function for NXP drivers David Marchand
2026-03-05 16:45   ` [RFC v3 4/7] drivers: cleanup devargs lookup in bus scan David Marchand
2026-03-05 16:56     ` Bruce Richardson
2026-03-05 16:45   ` [RFC v3 5/7] bus: factorize devargs lookup David Marchand
2026-03-05 17:06     ` Bruce Richardson
2026-03-05 17:10       ` David Marchand
2026-03-05 16:45   ` [RFC v3 6/7] bus: factorize device selection David Marchand
2026-03-05 17:30     ` Bruce Richardson
2026-03-09  9:50       ` David Marchand
2026-03-07 20:59     ` Robin Jarry
2026-03-05 16:45   ` [RFC v3 7/7] eal: configure initial device probing David Marchand
2026-03-05 17:33     ` Bruce Richardson
2026-03-07 21:05     ` Robin Jarry
2026-03-06  8:26   ` [RFC v3 0/7] Rework " David Marchand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox