[PATCH 16/23] bus: factorize driver reference

David Marchand david.marchand at redhat.com
Wed Apr 29 13:44:49 CEST 2026


Before this patch, setting the driver in the device object and error
rollback were the responsibility of each bus probe_device function.

This patch centralizes it in the EAL's local_dev_probe function.
The dev->driver field is now set before calling bus->probe_device,
ensuring that drivers can rely on it being set during probe.

On error, dev->driver is cleared only if the device was not previously
probed, to handle buses that support multiple probes
(RTE_PCI_DRV_PROBE_AGAIN).

As a consequence, each bus implementation no longer needs to set/clear
dev->driver and dev->device.driver.

In PCI bus, a side effect is that detecting a re-probe cannot use
rte_dev_is_probed (which checks dev->driver != NULL) anymore.
Switch to checking if intr_handle was allocated instead.

Signed-off-by: David Marchand <david.marchand at redhat.com>
---
 drivers/bus/auxiliary/auxiliary_common.c |  2 --
 drivers/bus/cdx/cdx.c                    |  2 --
 drivers/bus/dpaa/dpaa_bus.c              |  6 ++----
 drivers/bus/fslmc/fslmc_bus.c            |  1 -
 drivers/bus/ifpga/ifpga_bus.c            |  2 --
 drivers/bus/pci/pci_common.c             |  6 ++----
 drivers/bus/platform/platform.c          |  8 +-------
 drivers/bus/uacce/uacce.c                |  1 -
 drivers/bus/vmbus/vmbus_common.c         |  2 --
 lib/eal/common/eal_common_bus.c          |  7 +++++++
 lib/eal/common/eal_common_dev.c          | 12 ++++++++++++
 11 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index 206b69bbd4..ba8c35ebbe 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -120,8 +120,6 @@ auxiliary_probe_device(struct rte_driver *drv, struct rte_device *dev)
 		aux_dev->driver = NULL;
 		rte_intr_instance_free(aux_dev->intr_handle);
 		aux_dev->intr_handle = NULL;
-	} else {
-		aux_dev->device.driver = &aux_drv->driver;
 	}
 
 	return ret;
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index e1405d1372..c6a4da7692 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -332,8 +332,6 @@ cdx_probe_device(struct rte_driver *drv, struct rte_device *dev)
 		CDX_BUS_ERR("Probe CDX driver: %s device: %s failed: %d",
 			cdx_drv->driver.name, dev_name, ret);
 		goto error_probe;
-	} else {
-		cdx_dev->device.driver = &cdx_drv->driver;
 	}
 	cdx_dev->driver = cdx_drv;
 
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 7f4a85a91d..b7d0caaf61 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -800,12 +800,10 @@ dpaa_bus_probe_device(struct rte_driver *drv, struct rte_device *dev)
 	int ret;
 
 	ret = dpaa_drv->probe(dpaa_drv, dpaa_dev);
-	if (ret != 0) {
+	if (ret != 0)
 		DPAA_BUS_ERR("unable to probe: %s", dpaa_dev->name);
-	} else {
+	else
 		dpaa_dev->driver = dpaa_drv;
-		dpaa_dev->device.driver = &dpaa_drv->driver;
-	}
 
 	return ret;
 }
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 29ef3b58cf..ae69bd0da2 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -524,7 +524,6 @@ fslmc_bus_probe_device(struct rte_driver *driver, struct rte_device *rte_dev)
 		DPAA2_BUS_ERR("Unable to probe");
 	} else {
 		dev->driver = drv;
-		dev->device.driver = &drv->driver;
 		DPAA2_BUS_INFO("%s Plugged",  dev->device.name);
 	}
 
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index b2eb4f4413..a79a287fbe 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -281,8 +281,6 @@ ifpga_probe_device(struct rte_driver *drv, struct rte_device *dev)
 	ret = afu_drv->probe(afu_dev);
 	if (ret)
 		afu_dev->driver = NULL;
-	else
-		afu_dev->device.driver = &afu_drv->driver;
 
 	return ret;
 }
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index a507360ef6..5c37c5e543 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -203,7 +203,7 @@ pci_probe_device(struct rte_driver *drv, struct rte_device *dev)
 	if (pci_dev->device.numa_node < 0 && rte_socket_count() > 1)
 		PCI_LOG(INFO, "Device %s is not NUMA-aware", pci_dev->name);
 
-	already_probed = rte_dev_is_probed(&pci_dev->device);
+	already_probed = (pci_dev->intr_handle != NULL);
 	if (already_probed && !(pci_drv->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
 		PCI_LOG(DEBUG, "Device %s is already probed", pci_dev->device.name);
 		return -EEXIST;
@@ -251,7 +251,7 @@ pci_probe_device(struct rte_driver *drv, struct rte_device *dev)
 		 * to use driver flags for adjusting configuration.
 		 */
 		pci_dev->driver = pci_drv;
-		if (pci_dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		if (pci_drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 			ret = rte_pci_map_device(pci_dev);
 			if (ret != 0) {
 				pci_dev->driver = NULL;
@@ -285,8 +285,6 @@ pci_probe_device(struct rte_driver *drv, struct rte_device *dev)
 		pci_dev->vfio_req_intr_handle = NULL;
 		rte_intr_instance_free(pci_dev->intr_handle);
 		pci_dev->intr_handle = NULL;
-	} else {
-		pci_dev->device.driver = &pci_drv->driver;
 	}
 
 	return ret;
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 01c8239cbb..671f36fac9 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -329,17 +329,11 @@ device_setup(struct rte_platform_device *pdev)
 static int
 driver_call_probe(struct rte_platform_driver *pdrv, struct rte_platform_device *pdev)
 {
-	int ret;
-
 	if (pdrv->probe != NULL) {
 		pdev->driver = pdrv;
-		ret = pdrv->probe(pdev);
-		if (ret)
-			return ret;
+		return pdrv->probe(pdev);
 	}
 
-	pdev->device.driver = &pdrv->driver;
-
 	return 0;
 }
 
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index b0deb39185..d4a18b2835 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -365,7 +365,6 @@ uacce_probe_device(struct rte_driver *drv, struct rte_device *dev)
 		UACCE_BUS_ERR("probe device %s with driver %s failed %d",
 			      dev_name, uacce_drv->driver.name, ret);
 	} else {
-		uacce_dev->device.driver = &uacce_drv->driver;
 		uacce_dev->driver = uacce_drv;
 		UACCE_BUS_DEBUG("probe device %s with driver %s success",
 				dev_name, uacce_drv->driver.name);
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index bd375ae6bb..43652c0487 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -119,8 +119,6 @@ vmbus_probe_device(struct rte_driver *drv, struct rte_device *dev)
 	if (ret != 0) {
 		vmbus_dev->driver = NULL;
 		rte_vmbus_unmap_device(vmbus_dev);
-	} else {
-		vmbus_dev->device.driver = &vmbus_drv->driver;
 	}
 
 	return ret;
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 94b7be5f5f..ca13ccce5b 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -86,6 +86,7 @@ rte_bus_generic_probe(struct rte_bus *bus)
 
 	TAILQ_FOREACH(dev, &bus->device_list, next) {
 		struct rte_driver *drv = NULL;
+		bool was_probed;
 		int ret;
 
 		if (rte_bus_device_is_ignored(bus, dev->name))
@@ -102,7 +103,13 @@ rte_bus_generic_probe(struct rte_bus *bus)
 		if (drv == NULL)
 			continue;
 
+		was_probed = rte_dev_is_probed(dev);
+		if (!was_probed)
+			dev->driver = drv;
 		ret = bus->probe_device(drv, dev);
+		if (!was_probed && ret != 0)
+			dev->driver = NULL;
+
 		if (ret > 0)
 			goto next_driver;
 
diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
index 9047a01c4a..48b631532a 100644
--- a/lib/eal/common/eal_common_dev.c
+++ b/lib/eal/common/eal_common_dev.c
@@ -229,7 +229,19 @@ local_dev_probe(const char *devargs, struct rte_device **new_dev)
 		EAL_LOG(INFO, "Device %s is already probed", dev->name);
 		ret = -EEXIST;
 	} else {
+		bool was_probed = rte_dev_is_probed(dev);
+
+		/*
+		 * Reference driver structure.
+		 * This needs to be before .probe_device as some bus (like PCI) use
+		 * driver flags for adjusting configuration.
+		 */
+		if (!was_probed)
+			dev->driver = drv;
 		ret = dev->bus->probe_device(drv, dev);
+		if (!was_probed && ret != 0)
+			dev->driver = NULL;
+
 		if (ret > 0)
 			goto next_driver;
 	}
-- 
2.53.0



More information about the dev mailing list