From: David Marchand <david.marchand@redhat.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, stephen@networkplumber.org,
bruce.richardson@intel.com, fengchengwen@huawei.com,
longli@microsoft.com, hemant.agrawal@nxp.com,
Parav Pandit <parav@nvidia.com>, Xueming Li <xuemingl@nvidia.com>,
Nipun Gupta <nipun.gupta@amd.com>,
Nikhil Agarwal <nikhil.agarwal@amd.com>,
Sachin Saxena <sachin.saxena@nxp.com>,
Rosen Xu <rosen.xu@altera.com>, Chenbo Xia <chenbox@nvidia.com>,
Tomasz Duszynski <tduszynski@marvell.com>
Subject: [PATCH v2 07/10] bus: align unplug with device probe
Date: Thu, 18 Jun 2026 17:28:22 +0200 [thread overview]
Message-ID: <20260618152826.490569-8-david.marchand@redhat.com> (raw)
In-Reply-To: <20260618152826.490569-1-david.marchand@redhat.com>
Refactor bus unplug operations to be the counterpart of probe_device.
The (renamed) unplug operation now only handles:
- Driver removal (calling the driver's remove callback)
- Freeing probe-allocated resources (interrupts, mappings)
Device deletion (devargs removal, bus removal, freeing device
structure) is now handled only during bus cleanup, not in unplug.
Additionally, move driver pointer clearing from individual bus unplug
operations to EAL's local_dev_remove() where the unplug operation is
invoked. This centralizes driver lifecycle management and eliminates
code duplication across bus drivers.
For vdev, add a check in rte_vdev_uninit() since this public API can
be called on devices without a driver attached.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
doc/guides/prog_guide/device_hotplug.rst | 18 ++++---
drivers/bus/auxiliary/auxiliary_common.c | 46 ++++++----------
drivers/bus/cdx/cdx.c | 29 ++--------
drivers/bus/fslmc/fslmc_bus.c | 7 +--
drivers/bus/ifpga/ifpga_bus.c | 63 ++++++++++------------
drivers/bus/pci/pci_common.c | 57 ++++----------------
drivers/bus/platform/platform.c | 16 +++---
drivers/bus/uacce/uacce.c | 67 ++++++++----------------
drivers/bus/vdev/vdev.c | 53 ++++++++-----------
lib/eal/common/eal_common_dev.c | 8 +--
lib/eal/include/bus_driver.h | 4 +-
11 files changed, 129 insertions(+), 239 deletions(-)
diff --git a/doc/guides/prog_guide/device_hotplug.rst b/doc/guides/prog_guide/device_hotplug.rst
index 7eb7fbcc2b..d21ba0c244 100644
--- a/doc/guides/prog_guide/device_hotplug.rst
+++ b/doc/guides/prog_guide/device_hotplug.rst
@@ -165,7 +165,7 @@ using ``rte_dev_event_callback_register()`` function.
on the device in question.
When ``RTE_DEV_EVENT_REMOVE`` event is delivered,
it indicates that the kernel has removed the device;
- the application should call ``rte_dev_remove()`` to clean up EAL resources.
+ the application should call ``rte_dev_remove()`` to unplug the device driver.
Event Notification Usage
@@ -256,13 +256,17 @@ When ``rte_dev_remove()`` is called, the following sequence occurs:
See `Multi-process Synchronization`_ for details.
#. **Device Unplug**:
- The bus's ``unplug()`` method is called (``dev->bus->unplug()``),
- which triggers the driver's remove function.
- This typically stops device operations, releases device resources,
- unmaps memory regions, and unregisters from subsystems.
+ The bus's ``unplug_device()`` method is called (``dev->bus->unplug_device()``),
+ which triggers the driver's remove function
+ and releases resources allocated during probe
+ (such as interrupt handles and device memory mappings).
-#. **Devargs Cleanup**:
- The devargs associated with the device are removed from the global list.
+.. note::
+
+ The device structure, its devargs, and its entry in the bus device list
+ are NOT freed during ``rte_dev_remove()``.
+ They remain in memory until ``rte_eal_cleanup()`` is called,
+ at which point the bus's ``cleanup()`` method handles complete device deletion.
Multi-process Synchronization
diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index 048aacf254..10f466e57a 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -122,13 +122,11 @@ auxiliary_probe_device(struct rte_driver *drv, struct rte_device *dev)
return ret;
}
-/*
- * Call the remove() function of the driver.
- */
static int
-rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device *dev)
+auxiliary_unplug_device(struct rte_device *rte_dev)
{
- const struct rte_auxiliary_driver *drv = RTE_BUS_DRIVER(dev->device.driver, *drv);
+ const struct rte_auxiliary_driver *drv = RTE_BUS_DRIVER(rte_dev->driver, *drv);
+ struct rte_auxiliary_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
int ret = 0;
AUXILIARY_LOG(DEBUG, "Driver %s remove auxiliary device %s on NUMA node %i",
@@ -140,8 +138,8 @@ rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device *dev)
return ret;
}
- /* clear driver structure */
- dev->device.driver = NULL;
+ rte_intr_instance_free(dev->intr_handle);
+ dev->intr_handle = NULL;
return 0;
}
@@ -181,22 +179,6 @@ rte_auxiliary_unregister(struct rte_auxiliary_driver *driver)
rte_bus_remove_driver(&auxiliary_bus, &driver->driver);
}
-static int
-auxiliary_unplug(struct rte_device *dev)
-{
- struct rte_auxiliary_device *adev = RTE_BUS_DEVICE(dev, *adev);
- int ret;
-
- ret = rte_auxiliary_driver_remove_dev(adev);
- if (ret == 0) {
- rte_bus_remove_device(&auxiliary_bus, &adev->device);
- rte_devargs_remove(dev->devargs);
- rte_intr_instance_free(adev->intr_handle);
- free(adev);
- }
- return ret;
-}
-
static int
auxiliary_cleanup(void)
{
@@ -206,13 +188,17 @@ auxiliary_cleanup(void)
RTE_BUS_FOREACH_DEV(dev, &auxiliary_bus) {
int ret;
- if (!rte_dev_is_probed(&dev->device))
- continue;
- ret = auxiliary_unplug(&dev->device);
- if (ret < 0) {
- rte_errno = errno;
- error = -1;
+ if (rte_dev_is_probed(&dev->device)) {
+ ret = auxiliary_unplug_device(&dev->device);
+ if (ret < 0) {
+ rte_errno = errno;
+ error = -1;
+ }
}
+
+ rte_devargs_remove(dev->device.devargs);
+ rte_bus_remove_device(&auxiliary_bus, &dev->device);
+ free(dev);
}
return error;
@@ -265,7 +251,7 @@ struct rte_bus auxiliary_bus = {
.find_device = rte_bus_generic_find_device,
.match = auxiliary_bus_match,
.probe_device = auxiliary_probe_device,
- .unplug = auxiliary_unplug,
+ .unplug_device = auxiliary_unplug_device,
.parse = auxiliary_parse,
.dma_map = auxiliary_dma_map,
.dma_unmap = auxiliary_dma_unmap,
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index 2443161e1a..c0b46a41ad 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -374,14 +374,11 @@ rte_cdx_unregister(struct rte_cdx_driver *driver)
rte_bus_remove_driver(&rte_cdx_bus, &driver->driver);
}
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
static int
-cdx_detach_dev(struct rte_cdx_device *dev)
+cdx_unplug_device(struct rte_device *rte_dev)
{
- const struct rte_cdx_driver *dr = RTE_BUS_DRIVER(dev->device.driver, *dr);
+ const struct rte_cdx_driver *dr = RTE_BUS_DRIVER(rte_dev->driver, *dr);
+ struct rte_cdx_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
int ret = 0;
CDX_BUS_DEBUG("detach device %s using driver: %s",
@@ -393,9 +390,6 @@ cdx_detach_dev(struct rte_cdx_device *dev)
return ret;
}
- /* clear driver structure */
- dev->device.driver = NULL;
-
rte_cdx_unmap_device(dev);
rte_intr_instance_free(dev->intr_handle);
@@ -404,21 +398,6 @@ cdx_detach_dev(struct rte_cdx_device *dev)
return 0;
}
-static int
-cdx_unplug(struct rte_device *dev)
-{
- struct rte_cdx_device *cdx_dev = RTE_BUS_DEVICE(dev, *cdx_dev);
- int ret;
-
- ret = cdx_detach_dev(cdx_dev);
- if (ret == 0) {
- rte_bus_remove_device(&rte_cdx_bus, &cdx_dev->device);
- rte_devargs_remove(dev->devargs);
- free(cdx_dev);
- }
- return ret;
-}
-
static int
cdx_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
{
@@ -452,7 +431,7 @@ static struct rte_bus rte_cdx_bus = {
.find_device = rte_bus_generic_find_device,
.match = cdx_bus_match,
.probe_device = cdx_probe_device,
- .unplug = cdx_unplug,
+ .unplug_device = cdx_unplug_device,
.parse = cdx_parse,
.dma_map = cdx_dma_map,
.dma_unmap = cdx_dma_unmap,
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index c7549a361a..dca4c5b182 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -520,6 +520,7 @@ fslmc_bus_probe_device(struct rte_driver *driver, struct rte_device *rte_dev)
return 0;
}
+ /* FIXME: probe_device should allocate intr_handle */
ret = drv->probe(drv, dev);
if (ret != 0) {
DPAA2_BUS_ERR("Unable to probe");
@@ -531,7 +532,7 @@ fslmc_bus_probe_device(struct rte_driver *driver, struct rte_device *rte_dev)
}
static int
-fslmc_bus_unplug(struct rte_device *rte_dev)
+fslmc_bus_unplug_device(struct rte_device *rte_dev)
{
struct rte_dpaa2_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
const struct rte_dpaa2_driver *drv = RTE_BUS_DRIVER(rte_dev->driver, *drv);
@@ -540,7 +541,7 @@ fslmc_bus_unplug(struct rte_device *rte_dev)
int ret = drv->remove(dev);
if (ret != 0)
return ret;
- dev->device.driver = NULL;
+ /* FIXME: unplug_device should free intr_handle */
DPAA2_BUS_INFO("%s Un-Plugged", dev->device.name);
return 0;
}
@@ -558,7 +559,7 @@ struct rte_bus rte_fslmc_bus = {
.get_iommu_class = rte_dpaa2_get_iommu_class,
.match = fslmc_bus_match,
.probe_device = fslmc_bus_probe_device,
- .unplug = fslmc_bus_unplug,
+ .unplug_device = fslmc_bus_unplug_device,
.dev_iterate = rte_bus_generic_dev_iterate,
};
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 2c22329f65..394b777916 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -276,6 +276,25 @@ ifpga_probe_device(struct rte_driver *drv, struct rte_device *dev)
return afu_drv->probe(afu_dev);
}
+static int
+ifpga_unplug_device(struct rte_device *dev)
+{
+ const struct rte_afu_driver *afu_drv = RTE_BUS_DRIVER(dev->driver, *afu_drv);
+ struct rte_afu_device *afu_dev = RTE_BUS_DEVICE(dev, *afu_dev);
+ int ret = 0;
+
+ if (afu_drv->remove) {
+ ret = afu_drv->remove(afu_dev);
+ if (ret)
+ return ret;
+ }
+
+ rte_intr_instance_free(afu_dev->intr_handle);
+ afu_dev->intr_handle = NULL;
+
+ return 0;
+}
+
/*
* Cleanup the content of the Intel FPGA bus, and call the remove() function
* for all registered devices.
@@ -287,52 +306,24 @@ ifpga_cleanup(void)
int error = 0;
RTE_BUS_FOREACH_DEV(afu_dev, &rte_ifpga_bus) {
- const struct rte_afu_driver *drv;
int ret = 0;
- if (!rte_dev_is_probed(&afu_dev->device))
- goto free;
- drv = RTE_BUS_DRIVER(afu_dev->device.driver, *drv);
- if (drv->remove == NULL)
- goto free;
-
- ret = drv->remove(afu_dev);
- if (ret < 0) {
- rte_errno = errno;
- error = -1;
+ if (rte_dev_is_probed(&afu_dev->device)) {
+ ret = ifpga_unplug_device(&afu_dev->device);
+ if (ret < 0) {
+ rte_errno = errno;
+ error = -1;
+ }
}
- afu_dev->device.driver = NULL;
-free:
- rte_bus_remove_device(&rte_ifpga_bus, &afu_dev->device);
rte_devargs_remove(afu_dev->device.devargs);
- rte_intr_instance_free(afu_dev->intr_handle);
+ rte_bus_remove_device(&rte_ifpga_bus, &afu_dev->device);
free(afu_dev);
}
return error;
}
-static int
-ifpga_unplug(struct rte_device *dev)
-{
- struct rte_afu_device *afu_dev = RTE_BUS_DEVICE(dev, *afu_dev);
- const struct rte_afu_driver *afu_drv = RTE_BUS_DRIVER(dev->driver, *afu_drv);
- int ret;
-
- ret = afu_drv->remove(afu_dev);
- if (ret)
- return ret;
-
- rte_bus_remove_device(&rte_ifpga_bus, &afu_dev->device);
-
- rte_devargs_remove(dev->devargs);
- rte_intr_instance_free(afu_dev->intr_handle);
- free(afu_dev);
- return 0;
-
-}
-
static int
ifpga_parse(const char *name, void *addr)
{
@@ -384,7 +375,7 @@ static struct rte_bus rte_ifpga_bus = {
.find_device = rte_bus_generic_find_device,
.match = ifpga_bus_match,
.probe_device = ifpga_probe_device,
- .unplug = ifpga_unplug,
+ .unplug_device = ifpga_unplug_device,
.parse = ifpga_parse,
};
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 791e9a7b49..bf4822f7ec 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -282,13 +282,10 @@ pci_probe_device(struct rte_driver *drv, struct rte_device *dev)
return ret;
}
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
+pci_unplug_device(struct rte_device *rte_dev)
{
+ struct rte_pci_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
struct rte_pci_addr *loc;
const struct rte_pci_driver *dr = RTE_BUS_DRIVER(dev->device.driver, *dr);
int ret = 0;
@@ -308,9 +305,6 @@ rte_pci_detach_dev(struct rte_pci_device *dev)
return ret;
}
- /* clear driver structure */
- dev->device.driver = NULL;
-
if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
/* unmap resources for devices that use igb_uio */
rte_pci_unmap_device(dev);
@@ -330,33 +324,17 @@ pci_cleanup(void)
int error = 0;
RTE_BUS_FOREACH_DEV(dev, &rte_pci_bus) {
- const struct rte_pci_driver *drv;
int ret = 0;
- if (!rte_dev_is_probed(&dev->device))
- goto free;
- drv = RTE_BUS_DRIVER(dev->device.driver, *drv);
- if (drv->remove == NULL)
- goto free;
-
- ret = drv->remove(dev);
- if (ret < 0) {
- rte_errno = errno;
- error = -1;
+ if (rte_dev_is_probed(&dev->device)) {
+ ret = pci_unplug_device(&dev->device);
+ if (ret < 0) {
+ rte_errno = errno;
+ error = -1;
+ }
}
- if (drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
- rte_pci_unmap_device(dev);
-
- dev->device.driver = NULL;
-
-free:
- /* free interrupt handles */
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
- rte_intr_instance_free(dev->vfio_req_intr_handle);
- dev->vfio_req_intr_handle = NULL;
-
+ rte_devargs_remove(dev->device.devargs);
rte_bus_remove_device(&rte_pci_bus, &dev->device);
pci_free(RTE_PCI_DEVICE_INTERNAL(dev));
}
@@ -521,21 +499,6 @@ pci_sigbus_handler(const void *failure_addr)
return ret;
}
-static int
-pci_unplug(struct rte_device *dev)
-{
- struct rte_pci_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
- int ret;
-
- ret = rte_pci_detach_dev(pdev);
- if (ret == 0) {
- rte_bus_remove_device(&rte_pci_bus, &pdev->device);
- rte_devargs_remove(dev->devargs);
- pci_free(RTE_PCI_DEVICE_INTERNAL(pdev));
- }
- return ret;
-}
-
static int
pci_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
{
@@ -784,7 +747,7 @@ struct rte_bus rte_pci_bus = {
.find_device = rte_bus_generic_find_device,
.match = pci_bus_match,
.probe_device = pci_probe_device,
- .unplug = pci_unplug,
+ .unplug_device = pci_unplug_device,
.parse = pci_parse,
.dev_compare = pci_dev_compare,
.devargs_parse = rte_pci_devargs_parse,
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 170a2e03d0..5b3c78a505 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -416,19 +416,15 @@ device_release_driver(struct rte_platform_device *pdev)
if (ret)
PLATFORM_LOG_LINE(WARNING, "failed to remove %s", pdev->name);
}
-
- pdev->device.driver = NULL;
}
static int
-platform_bus_unplug(struct rte_device *dev)
+platform_bus_unplug_device(struct rte_device *dev)
{
struct rte_platform_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
device_release_driver(pdev);
device_cleanup(pdev);
- rte_devargs_remove(pdev->device.devargs);
- free(pdev);
return 0;
}
@@ -501,10 +497,12 @@ platform_bus_cleanup(void)
struct rte_platform_device *pdev;
RTE_BUS_FOREACH_DEV(pdev, &platform_bus) {
+ if (rte_dev_is_probed(&pdev->device))
+ platform_bus_unplug_device(&pdev->device);
+
+ rte_devargs_remove(pdev->device.devargs);
rte_bus_remove_device(&platform_bus, &pdev->device);
- if (!rte_dev_is_probed(&pdev->device))
- continue;
- platform_bus_unplug(&pdev->device);
+ free(pdev);
}
return 0;
@@ -516,7 +514,7 @@ static struct rte_bus platform_bus = {
.find_device = rte_bus_generic_find_device,
.match = platform_bus_match,
.probe_device = platform_bus_probe_device,
- .unplug = platform_bus_unplug,
+ .unplug_device = platform_bus_unplug_device,
.parse = platform_bus_parse,
.dma_map = platform_bus_dma_map,
.dma_unmap = platform_bus_dma_unmap,
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 8a3c55b248..bfe1f26557 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -385,40 +385,10 @@ uacce_probe_device(struct rte_driver *drv, struct rte_device *dev)
}
static int
-uacce_cleanup(void)
+uacce_unplug_device(struct rte_device *rte_dev)
{
- struct rte_uacce_device *dev;
- int error = 0;
-
- RTE_BUS_FOREACH_DEV(dev, &uacce_bus) {
- const struct rte_uacce_driver *dr;
- int ret = 0;
-
- if (!rte_dev_is_probed(&dev->device))
- goto free;
- dr = RTE_BUS_DRIVER(dev->device.driver, *dr);
- if (dr->remove == NULL)
- goto free;
-
- ret = dr->remove(dev);
- if (ret < 0) {
- rte_errno = errno;
- error = -1;
- }
- dev->device.driver = NULL;
-
-free:
- rte_bus_remove_device(&uacce_bus, &dev->device);
- free(dev);
- }
-
- return error;
-}
-
-static int
-uacce_detach_dev(struct rte_uacce_device *dev)
-{
- const struct rte_uacce_driver *dr = RTE_BUS_DRIVER(dev->device.driver, *dr);
+ const struct rte_uacce_driver *dr = RTE_BUS_DRIVER(rte_dev->driver, *dr);
+ struct rte_uacce_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
int ret = 0;
UACCE_BUS_DEBUG("detach device %s using driver: %s", dev->device.name, dr->driver.name);
@@ -429,25 +399,32 @@ uacce_detach_dev(struct rte_uacce_device *dev)
return ret;
}
- dev->device.driver = NULL;
-
return 0;
}
static int
-uacce_unplug(struct rte_device *dev)
+uacce_cleanup(void)
{
- struct rte_uacce_device *uacce_dev = RTE_BUS_DEVICE(dev, *uacce_dev);
- int ret;
+ struct rte_uacce_device *dev;
+ int error = 0;
- ret = uacce_detach_dev(uacce_dev);
- if (ret == 0) {
- rte_bus_remove_device(&uacce_bus, &uacce_dev->device);
- rte_devargs_remove(dev->devargs);
- free(uacce_dev);
+ RTE_BUS_FOREACH_DEV(dev, &uacce_bus) {
+ int ret = 0;
+
+ if (rte_dev_is_probed(&dev->device)) {
+ ret = uacce_unplug_device(&dev->device);
+ if (ret < 0) {
+ rte_errno = errno;
+ error = -1;
+ }
+ }
+
+ rte_devargs_remove(dev->device.devargs);
+ rte_bus_remove_device(&uacce_bus, &dev->device);
+ free(dev);
}
- return ret;
+ return error;
}
static int
@@ -577,7 +554,7 @@ static struct rte_bus uacce_bus = {
.cleanup = uacce_cleanup,
.match = uacce_bus_match,
.probe_device = uacce_probe_device,
- .unplug = uacce_unplug,
+ .unplug_device = uacce_unplug_device,
.find_device = rte_bus_generic_find_device,
.parse = uacce_parse,
.dev_iterate = rte_bus_generic_dev_iterate,
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 09221ccdea..7e94f86e28 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -343,19 +343,15 @@ rte_vdev_init(const char *name, const char *args)
}
static int
-vdev_remove_driver(struct rte_vdev_device *dev)
+vdev_unplug_device(struct rte_device *rte_dev)
{
- const char *name = rte_vdev_device_name(dev);
- const struct rte_vdev_driver *driver;
+ const struct rte_vdev_driver *driver = RTE_BUS_DRIVER(rte_dev->driver, *driver);
+ struct rte_vdev_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
- if (!dev->device.driver) {
- VDEV_LOG(DEBUG, "no driver attach to device %s", name);
- return 1;
- }
+ if (driver->remove)
+ return driver->remove(dev);
- driver = RTE_BUS_DRIVER(dev->device.driver, *driver);
-
- return driver->remove(dev);
+ return 0;
}
RTE_EXPORT_SYMBOL(rte_vdev_uninit)
@@ -376,7 +372,12 @@ rte_vdev_uninit(const char *name)
goto unlock;
}
- ret = vdev_remove_driver(dev);
+ if (rte_dev_is_probed(&dev->device)) {
+ ret = vdev_unplug_device(&dev->device);
+ } else {
+ VDEV_LOG(DEBUG, "no driver attach to device %s", name);
+ ret = 1;
+ }
if (ret)
goto unlock;
@@ -553,27 +554,21 @@ vdev_cleanup(void)
struct rte_vdev_device *dev;
int error = 0;
+ rte_spinlock_recursive_lock(&vdev_device_list_lock);
RTE_BUS_FOREACH_DEV(dev, &rte_vdev_bus) {
- const struct rte_vdev_driver *drv;
int ret;
- if (!rte_dev_is_probed(&dev->device))
- goto free;
-
- drv = RTE_BUS_DRIVER(dev->device.driver, *drv);
-
- if (drv->remove == NULL)
- goto free;
-
- ret = drv->remove(dev);
- if (ret < 0)
- error = -1;
+ if (rte_dev_is_probed(&dev->device)) {
+ ret = vdev_unplug_device(&dev->device);
+ if (ret < 0)
+ error = -1;
+ }
- dev->device.driver = NULL;
-free:
+ rte_devargs_remove(dev->device.devargs);
rte_bus_remove_device(&rte_vdev_bus, &dev->device);
free(dev);
}
+ rte_spinlock_recursive_unlock(&vdev_device_list_lock);
return error;
}
@@ -591,12 +586,6 @@ vdev_find_device(const struct rte_bus *bus, const struct rte_device *start,
return dev;
}
-static int
-vdev_unplug(struct rte_device *dev)
-{
- return rte_vdev_uninit(dev->name);
-}
-
static enum rte_iova_mode
vdev_get_iommu_class(void)
{
@@ -623,7 +612,7 @@ static struct rte_bus rte_vdev_bus = {
.find_device = vdev_find_device,
.match = vdev_bus_match,
.probe_device = vdev_probe_device,
- .unplug = vdev_unplug,
+ .unplug_device = vdev_unplug_device,
.parse = vdev_parse,
.dma_map = vdev_dma_map,
.dma_unmap = vdev_dma_unmap,
diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
index 2a2103ec57..762ed09e21 100644
--- a/lib/eal/common/eal_common_dev.c
+++ b/lib/eal/common/eal_common_dev.c
@@ -385,19 +385,21 @@ local_dev_remove(struct rte_device *dev)
{
int ret;
- if (dev->bus->unplug == NULL) {
- EAL_LOG(ERR, "Function unplug not supported by bus (%s)",
+ if (dev->bus->unplug_device == NULL) {
+ EAL_LOG(ERR, "Function unplug_device not supported by bus (%s)",
dev->bus->name);
return -ENOTSUP;
}
- ret = dev->bus->unplug(dev);
+ ret = dev->bus->unplug_device(dev);
if (ret) {
EAL_LOG(ERR, "Driver cannot detach the device (%s)",
dev->name);
return (ret < 0) ? ret : -ENOENT;
}
+ dev->driver = NULL;
+
return 0;
}
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index 9711e6712b..fde55ff06d 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -101,7 +101,7 @@ typedef int (*rte_bus_probe_device_t)(struct rte_driver *drv, struct rte_device
* 0 on success.
* !0 on error.
*/
-typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
+typedef int (*rte_bus_unplug_device_t)(struct rte_device *dev);
/**
* Bus specific parsing function.
@@ -323,7 +323,7 @@ struct rte_bus {
rte_bus_find_device_t find_device; /**< Find a device on the bus */
rte_bus_match_t match; /**< Check if driver matches device */
rte_bus_probe_device_t probe_device; /**< Probe single device with driver */
- rte_bus_unplug_t unplug; /**< Remove single device from driver */
+ rte_bus_unplug_device_t unplug_device; /**< Remove single device from driver */
rte_bus_parse_t parse; /**< Parse a device name */
rte_bus_dev_compare_t dev_compare; /**< Compare two device names */
rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
--
2.53.0
next prev parent reply other threads:[~2026-06-18 15:29 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-11 9:45 [PATCH 00/13] Bus cleanup infrastructure and fixes David Marchand
2026-06-11 9:45 ` [PATCH 01/13] bus: fix reference to plug callback David Marchand
2026-06-11 9:45 ` [PATCH 02/13] dma/idxd: remove next pointer in bus specific device David Marchand
2026-06-11 9:45 ` [PATCH 03/13] bus/vdev: remove driver setting in probe David Marchand
2026-06-11 9:45 ` [PATCH 04/13] drivers/bus: cleanup device freeing in NXP bus David Marchand
2026-06-11 9:45 ` [PATCH 05/13] drivers/bus: allocate interrupt during probing " David Marchand
2026-06-11 9:45 ` [PATCH 06/13] bus/pci: fix mapping leak in bus cleanup David Marchand
2026-06-11 9:45 ` [PATCH 07/13] bus/vmbus: fix interrupt leak in cleanup David Marchand
2026-06-11 9:45 ` [PATCH 08/13] bus/vmbus: allocate interrupt during probing David Marchand
2026-06-15 19:13 ` [EXTERNAL] " Long Li
2026-06-11 9:45 ` [PATCH 09/13] bus: align unplug with device probe David Marchand
2026-06-11 9:45 ` [PATCH 10/13] bus: implement cleanup in EAL David Marchand
2026-06-11 9:45 ` [PATCH 11/13] bus/dpaa: support unplug David Marchand
2026-06-11 9:45 ` [PATCH 12/13] bus/vmbus: store name in bus specific device David Marchand
2026-06-11 9:45 ` [PATCH 13/13] bus/vmbus: support unplug David Marchand
2026-06-11 10:09 ` [PATCH 00/13] Bus cleanup infrastructure and fixes David Marchand
2026-06-15 19:14 ` [EXTERNAL] " Long Li
2026-06-15 23:55 ` Long Li
2026-06-16 6:55 ` David Marchand
2026-06-16 7:47 ` David Marchand
2026-06-17 9:16 ` Hemant Agrawal
2026-06-18 8:39 ` David Marchand
2026-06-18 15:28 ` David Marchand
2026-06-18 15:28 ` [PATCH v2 00/10] " David Marchand
2026-06-18 15:28 ` [PATCH v2 01/10] bus: fix reference to plug callback David Marchand
2026-06-22 9:49 ` Bruce Richardson
2026-06-18 15:28 ` [PATCH v2 02/10] dma/idxd: remove next pointer in bus specific device David Marchand
2026-06-22 9:48 ` Bruce Richardson
2026-06-18 15:28 ` [PATCH v2 03/10] bus/vdev: remove driver setting in probe David Marchand
2026-06-18 15:28 ` [PATCH v2 04/10] bus/pci: fix mapping leak in bus cleanup David Marchand
2026-06-18 15:28 ` [PATCH v2 05/10] bus/vmbus: fix interrupt leak in cleanup David Marchand
2026-06-19 22:04 ` [EXTERNAL] " Long Li
2026-06-18 15:28 ` [PATCH v2 06/10] bus/vmbus: allocate interrupt during probing David Marchand
2026-06-19 22:05 ` [EXTERNAL] " Long Li
2026-06-18 15:28 ` David Marchand [this message]
2026-06-22 10:19 ` [PATCH v2 07/10] bus: align unplug with device probe Bruce Richardson
2026-06-22 12:44 ` David Marchand
2026-06-18 15:28 ` [PATCH v2 08/10] bus: implement cleanup in EAL David Marchand
2026-06-22 10:26 ` Bruce Richardson
2026-06-18 15:28 ` [PATCH v2 09/10] bus/vmbus: store name in bus specific device David Marchand
2026-06-22 10:28 ` Bruce Richardson
2026-06-18 15:28 ` [PATCH v2 10/10] bus/vmbus: support unplug David Marchand
2026-06-23 10:54 ` [PATCH v3 00/11] Bus cleanup infrastructure and fixes David Marchand
2026-06-23 10:54 ` [PATCH v3 01/11] bus: fix reference to plug callback David Marchand
2026-06-23 10:54 ` [PATCH v3 02/11] dma/idxd: remove next pointer in bus specific device David Marchand
2026-06-23 10:54 ` [PATCH v3 03/11] bus/vdev: remove driver setting in probe David Marchand
2026-06-23 10:54 ` [PATCH v3 04/11] bus/pci: fix mapping leak in bus cleanup David Marchand
2026-06-23 10:54 ` [PATCH v3 05/11] bus/vmbus: fix interrupt leak in cleanup David Marchand
2026-06-23 10:54 ` [PATCH v3 06/11] bus/vmbus: allocate interrupt during probing David Marchand
2026-06-23 10:54 ` [PATCH v3 07/11] bus/ifpga: " David Marchand
2026-06-23 11:25 ` Bruce Richardson
2026-06-23 10:54 ` [PATCH v3 08/11] bus: align unplug with device probe David Marchand
2026-06-23 10:54 ` [PATCH v3 09/11] bus: implement cleanup in EAL David Marchand
2026-06-23 10:54 ` [PATCH v3 10/11] bus/vmbus: store name in bus specific device David Marchand
2026-06-23 10:54 ` [PATCH v3 11/11] bus/vmbus: support unplug David Marchand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260618152826.490569-8-david.marchand@redhat.com \
--to=david.marchand@redhat.com \
--cc=bruce.richardson@intel.com \
--cc=chenbox@nvidia.com \
--cc=dev@dpdk.org \
--cc=fengchengwen@huawei.com \
--cc=hemant.agrawal@nxp.com \
--cc=longli@microsoft.com \
--cc=nikhil.agarwal@amd.com \
--cc=nipun.gupta@amd.com \
--cc=parav@nvidia.com \
--cc=rosen.xu@altera.com \
--cc=sachin.saxena@nxp.com \
--cc=stephen@networkplumber.org \
--cc=tduszynski@marvell.com \
--cc=thomas@monjalon.net \
--cc=xuemingl@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox