From 60b7ff32f3672a89a9c7bd702171eced1ccbc9a0 Mon Sep 17 00:00:00 2001 From: Darek Stojaczyk Date: Thu, 22 Nov 2018 15:34:33 +0100 Subject: [PATCH] pci: allow devices to be attached by surprise With all the error checks and segfault preventions in place, we can finally enable hotplug in a multi-process scenario for DPDK 18.11+. If a device is attached in the primary process, it will send an attach IPC request to the secondary process which needs to succeed. Until now it would get rejected, and the attach would fail in all the processes. The device in secondary process will be now probed by DPDK and will be put into the process local SPDK list of devices to be locally attached. Either SPDK will attach it sometime later on any attach/enumerate request, or DPDK will remove it automatically once the same device in the primary process gets removed. We also allow the surprise attach in primary processes, as it's technically possible for the pci devices (NVMe) to be attached exclusively from the secondary process. The fact that the NVMe stack doesn't support it is another story. Currently the NVMe stack will handle the failure by itself just fine. Change-Id: Ia24a8b4610cc7c659f59a2fdda9d8a78e58af873 Signed-off-by: Darek Stojaczyk Reviewed-on: https://review.gerrithub.io/434416 (master) Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448378 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/env_dpdk/pci.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 8d395273e..5993f3f15 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -85,14 +85,17 @@ spdk_pci_device_init(struct rte_pci_driver *_drv, struct spdk_pci_device *dev; int rc; +#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0) if (!driver->cb_fn) { #if RTE_VERSION < RTE_VERSION_NUM(17, 02, 0, 1) rte_eal_pci_unmap_device(_dev); #endif - /* Return a positive value to indicate that this device does not belong to this driver, but - * this isn't an error. */ + /* Return a positive value to indicate that this device does + * not belong to this driver, but this isn't an error. + */ return 1; } +#endif dev = calloc(1, sizeof(*dev)); if (dev == NULL) { @@ -112,13 +115,15 @@ spdk_pci_device_init(struct rte_pci_driver *_drv, dev->id.subdevice_id = _dev->id.subsystem_device_id; dev->socket_id = _dev->device.numa_node; - rc = driver->cb_fn(driver->cb_arg, dev); - if (rc != 0) { - free(dev); - return rc; + if (driver->cb_fn != NULL) { + rc = driver->cb_fn(driver->cb_arg, dev); + if (rc != 0) { + free(dev); + return rc; + } + dev->attached = true; } - dev->attached = true; TAILQ_INSERT_TAIL(&g_pci_devices, dev, tailq); spdk_vtophys_pci_device_added(dev->dev_handle); return 0;