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 <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/434412 (master)
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448373
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Darek Stojaczyk 2018-11-20 20:57:38 +01:00
parent 0cd37ba171
commit 5980c657bd
2 changed files with 6 additions and 1 deletions

View File

@ -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;
};

View File

@ -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)