From 0cee787483b5739cd8bf0edcb09b80bb52947781 Mon Sep 17 00:00:00 2001 From: Darek Stojaczyk Date: Tue, 20 Nov 2018 20:57:38 +0100 Subject: [PATCH] pci: prevent surprise DPDK device removal In DPDK 18.11, a device can be potentially detached not only upon an SPDK request, but also directly from within the DPDK itself. In a multi-process scenario, when one process detaches the PCI device, an IPC message - detach request - will be sent to every other process in the same shared memory group. As we don't propagate the removal notification to upper layers, the still-referenced rte_pci_device object will just disappear at one moment. SPDK is still not ready for supporting the above case and will try to avoid it, but just in case some detach request slips through, then this patch provides the sanity checks preventing SPDK from crashing. Change-Id: I3e35d8efb33085163b9acd8a565e86a4221df844 Signed-off-by: Darek Stojaczyk Reviewed-on: https://review.gerrithub.io/434412 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris --- lib/env_dpdk/env_internal.h | 1 + lib/env_dpdk/pci.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/env_dpdk/env_internal.h b/lib/env_dpdk/env_internal.h index 267f35a79..c7ae6f1b2 100644 --- a/lib/env_dpdk/env_internal.h +++ b/lib/env_dpdk/env_internal.h @@ -74,6 +74,7 @@ extern struct rte_pci_bus rte_pci_bus; struct spdk_pci_device { struct rte_pci_device *dev_handle; + bool attached; TAILQ_ENTRY(spdk_pci_device) tailq; }; diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index c0fe829d0..2f5cc6700 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -73,6 +73,7 @@ spdk_pci_device_init(struct rte_pci_driver *driver, return rc; } + dev->attached = true; TAILQ_INSERT_TAIL(&g_pci_devices, dev, tailq); spdk_vtophys_pci_device_added(dev->dev_handle); return 0; @@ -89,7 +90,8 @@ spdk_pci_device_fini(struct rte_pci_device *_dev) } } - if (dev == NULL) { + if (dev == NULL || dev->attached) { + /* The device might be still referenced somewhere in SPDK. */ return -1; } @@ -105,6 +107,8 @@ spdk_pci_device_detach(struct spdk_pci_device *dev) { struct rte_pci_device *device = dev->dev_handle; + assert(dev->attached); + dev->attached = false; #if RTE_VERSION >= RTE_VERSION_NUM(18, 11, 0, 0) rte_eal_hotplug_remove("pci", device->device.name); #elif RTE_VERSION >= RTE_VERSION_NUM(17, 11, 0, 3)