From 5980c657bd6e003a6654fbd83ff9aa88d20bd4ba 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 (master) Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448373 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- 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)