diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 124735ae2..49cbd1d79 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -33,6 +33,7 @@ #include "env_internal.h" +#include #include "spdk/env.h" #define SYSFS_PCI_DRIVERS "/sys/bus/pci/drivers" @@ -97,9 +98,9 @@ spdk_cfg_write_rte(struct spdk_pci_device *dev, void *value, uint32_t len, uint3 } static void -spdk_detach_rte(struct spdk_pci_device *dev) +spdk_detach_rte_cb(void *_dev) { - struct rte_pci_device *rte_dev = dev->dev_handle; + struct rte_pci_device *rte_dev = _dev; #if RTE_VERSION >= RTE_VERSION_NUM(18, 11, 0, 0) char bdf[32]; @@ -114,6 +115,20 @@ spdk_detach_rte(struct spdk_pci_device *dev) #endif } +static void +spdk_detach_rte(struct spdk_pci_device *dev) +{ + /* The device was already marked as available and could be attached + * again while we go asynchronous, so we explicitly forbid that. + */ + dev->internal.pending_removal = true; + if (spdk_process_is_primary()) { + rte_eal_alarm_set(10, spdk_detach_rte_cb, dev->dev_handle); + } else { + spdk_detach_rte_cb(dev->dev_handle); + } +} + void spdk_pci_driver_register(struct spdk_pci_driver *driver) { @@ -317,7 +332,7 @@ spdk_pci_device_attach(struct spdk_pci_driver *driver, } if (dev != NULL && dev->internal.driver == driver) { - if (dev->internal.attached) { + if (dev->internal.attached || dev->internal.pending_removal) { pthread_mutex_unlock(&g_pci_mutex); return -1; } @@ -377,7 +392,9 @@ spdk_pci_enumerate(struct spdk_pci_driver *driver, pthread_mutex_lock(&g_pci_mutex); TAILQ_FOREACH(dev, &g_pci_devices, internal.tailq) { - if (dev->internal.attached || dev->internal.driver != driver) { + if (dev->internal.attached || + dev->internal.driver != driver || + dev->internal.pending_removal) { continue; }