From 301c5aeec9f1ef3bed61c55502385d08565acdb1 Mon Sep 17 00:00:00 2001 From: Jin Yu Date: Mon, 4 Nov 2019 23:02:05 +0800 Subject: [PATCH] pci: fix the hotplug issue DPDK intr thread is designed that it can't unregister the src callback in this callback handler. So I think we can't detach the PCI device in the hotremove callback as it needs to unregister the VFIO notification callback which will be not successful but it still can free the device. So at the next req notification in the handler function, we meet the freed device. Fix #994 Change-Id: Id4b45a2d0fe6b45b132355d59471bc80240fad70 Signed-off-by: Jin Yu Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/473176 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker --- lib/env_dpdk/pci.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) 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