diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 2e9d4070c..5cfa63619 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -176,6 +176,12 @@ spdk_pci_driver_register(struct spdk_pci_driver *driver) } #if RTE_VERSION >= RTE_VERSION_NUM(18, 5, 0, 0) +static void +spdk_pci_device_rte_hotremove_cb(void *dev) +{ + spdk_detach_rte((struct spdk_pci_device *)dev); +} + static void spdk_pci_device_rte_hotremove(const char *device_name, enum rte_dev_event_type event, @@ -191,7 +197,6 @@ spdk_pci_device_rte_hotremove(const char *device_name, pthread_mutex_lock(&g_pci_mutex); TAILQ_FOREACH(dev, &g_pci_devices, internal.tailq) { struct rte_pci_device *rte_dev = dev->dev_handle; - if (strcmp(rte_dev->name, device_name) == 0 && !dev->internal.pending_removal) { can_detach = !dev->internal.attached; @@ -203,8 +208,17 @@ spdk_pci_device_rte_hotremove(const char *device_name, pthread_mutex_unlock(&g_pci_mutex); if (dev != NULL && can_detach) { - /* if device is not attached, we can remove it right away. */ - spdk_detach_rte(dev); + /* If device is not attached, we can remove it right away. + * + * Because the user's callback is invoked in eal interrupt + * callback, the interrupt callback need to be finished before + * it can be unregistered when detaching device. So finish + * callback soon and use a deferred removal to detach device + * is need. It is a workaround, once the device detaching be + * moved into the eal in the future, the deferred removal could + * be deleted. + */ + rte_eal_alarm_set(1, spdk_pci_device_rte_hotremove_cb, dev); } } #endif