[V5,1/5] drivers/bus: restore driver assignment at front of probing

Message ID 20230131033317.2155-2-lihuisong@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series app/testpmd: support multiple process attach and detach port |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

lihuisong (C) Jan. 31, 2023, 3:33 a.m. UTC
  The driver assignment was moved back at the end of the device probing
because there is no something to use rte_driver during the phase of
probing. See commit 391797f04208 ("drivers/bus: move driver assignment
to end of probing")

However, it is necessary for probing callback to reference rte_driver
before probing. For example, probing callback may call some APIs which
access the rte_pci_driver::driver by the device::driver pointer to get
driver information. In this case, a segment fault will occur in probing
callback if there is not this assignment.

Further, some comments in code need to be updated if we do that. The
driver pointer in rte_device is set before probing and needs to be reset
if probing failed. And rte_dev_is_probed can not be called inside probing.

Fixes: 391797f04208 ("drivers/bus: move driver assignment to end of probing")
Cc: stable@dpdk.org

Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 drivers/bus/auxiliary/auxiliary_common.c |  9 +++++++--
 drivers/bus/dpaa/dpaa_bus.c              |  9 +++++++--
 drivers/bus/fslmc/fslmc_bus.c            |  8 +++++++-
 drivers/bus/ifpga/ifpga_bus.c            | 12 +++++++++---
 drivers/bus/pci/pci_common.c             |  9 +++++++--
 drivers/bus/vdev/vdev.c                  | 10 ++++++++--
 drivers/bus/vmbus/vmbus_common.c         |  9 +++++++--
 7 files changed, 52 insertions(+), 14 deletions(-)
  

Patch

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index ff1369353a..13cb3fe0f8 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -132,16 +132,21 @@  rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver *drv,
 	}
 
 	dev->driver = drv;
+	/*
+	 * Reference rte_driver before probing so as to this pointer can
+	 * be used to get driver information in case of segment fault in
+	 * probing callback.
+	 */
+	dev->device.driver = &drv->driver;
 
 	AUXILIARY_LOG(INFO, "Probe auxiliary driver: %s device: %s (NUMA node %i)",
 		      drv->driver.name, dev->name, dev->device.numa_node);
 	ret = drv->probe(drv, dev);
 	if (ret != 0) {
 		dev->driver = NULL;
+		dev->device.driver = NULL;
 		rte_intr_instance_free(dev->intr_handle);
 		dev->intr_handle = NULL;
-	} else {
-		dev->device.driver = &drv->driver;
 	}
 
 	return ret;
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index e57159f5d8..f1b817e58c 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -693,17 +693,22 @@  rte_dpaa_bus_probe(void)
 			    (dev->device.devargs &&
 			     dev->device.devargs->policy == RTE_DEV_BLOCKED))
 				continue;
-
+			/*
+			 * Reference rte_driver before probing so as to this
+			 * pointer can be used to get driver information in case
+			 * of segment fault in probing callback.
+			 */
+			dev->device.driver = &drv->driver;
 			if (probe_all ||
 			    (dev->device.devargs &&
 			     dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
 				ret = drv->probe(drv, dev);
 				if (ret) {
+					dev->device.driver = NULL;
 					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 57bfb5111a..4bc0c6d3d4 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -471,15 +471,21 @@  rte_fslmc_probe(void)
 				continue;
 			}
 
+			/*
+			 * Reference rte_driver before probing so as to this
+			 * pointer can be used to get driver information in case
+			 * of segment fault in probing callback.
+			 */
+			dev->device.driver = &drv->driver;
 			if (probe_all ||
 			   (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_ALLOWED)) {
 				ret = drv->probe(drv, dev);
 				if (ret) {
+					dev->device.driver = NULL;
 					DPAA2_BUS_ERR("Unable to probe");
 				} else {
 					dev->driver = drv;
-					dev->device.driver = &drv->driver;
 				}
 			}
 			break;
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index bb943b58b5..5f23446f41 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -293,13 +293,19 @@  ifpga_probe_one_driver(struct rte_afu_driver *drv,
 
 	/* reference driver structure */
 	afu_dev->driver = drv;
+	/*
+	 * Reference rte_driver before probing so as to this pointer can
+	 * be used to get driver information in case of segment fault in
+	 * probing callback.
+	 */
+	afu_dev->device.driver = &drv->driver;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
-	if (ret)
+	if (ret) {
 		afu_dev->driver = NULL;
-	else
-		afu_dev->device.driver = &drv->driver;
+		afu_dev->device.driver = NULL;
+	}
 
 	return ret;
 }
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index bc3a7f39fe..efaa1792e9 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -302,6 +302,12 @@  rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 				return ret;
 			}
 		}
+		/*
+		 * Reference rte_driver before probing so as to this pointer can
+		 * be used to get driver information in case of segment fault in
+		 * probing callback.
+		 */
+		dev->device.driver = &dr->driver;
 	}
 
 	RTE_LOG(INFO, EAL, "Probe PCI driver: %s (%x:%x) device: "PCI_PRI_FMT" (socket %i)\n",
@@ -314,6 +320,7 @@  rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
+		dev->device.driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
 			/* Don't unmap if device is unsupported and
 			 * driver needs mapped resources.
@@ -325,8 +332,6 @@  rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->vfio_req_intr_handle = NULL;
 		rte_intr_instance_free(dev->intr_handle);
 		dev->intr_handle = NULL;
-	} else {
-		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 41bc07dde7..2e3f0f2e12 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -207,9 +207,15 @@  vdev_probe_all_drivers(struct rte_vdev_device *dev)
 		return -1;
 	}
 
+	/*
+	 * Reference rte_driver before probing so as to this pointer can
+	 * be used to get driver information in case of segment fault in
+	 * probing callback.
+	 */
+	dev->device.driver = &driver->driver;
 	ret = driver->probe(dev);
-	if (ret == 0)
-		dev->device.driver = &driver->driver;
+	if (ret != 0)
+		dev->device.driver = NULL;
 	return ret;
 }
 
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index 8d32d66504..feb1651984 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -110,6 +110,12 @@  vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* reference driver structure */
 	dev->driver = dr;
+	/*
+	 * Reference rte_driver before probing so as to this pointer can
+	 * be used to get driver information in case of segment fault in
+	 * probing callback.
+	 */
+	dev->device.driver = &dr->driver;
 
 	if (dev->device.numa_node < 0 && rte_socket_count() > 1)
 		VMBUS_LOG(INFO, "Device %s is not NUMA-aware", guid);
@@ -119,9 +125,8 @@  vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	ret = dr->probe(dr, dev);
 	if (ret) {
 		dev->driver = NULL;
+		dev->device.driver = NULL;
 		rte_vmbus_unmap_device(dev);
-	} else {
-		dev->device.driver = &dr->driver;
 	}
 
 	return ret;