diff --git a/CHANGELOG.md b/CHANGELOG.md index 616363739..0888a5f05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,12 @@ Added `spdk_nvme_qpair_get_optimal_poll_group` function and `qpair_get_optimal_p function pointer in spdk_nvmf_transport_ops structure in order to add the qpair to the most suitable polling group. +Added spdk_nvme_set_hotplug_filter API to allow applications to choose which +hot-inserted SSDs should be probed. This is useful for use cases where multiple +independent SPDK processes are running on one node. The filter function can +then be implemented in these processes to decide which SSDs to probe based on +the new SSD's PCI address. + ## v21.01: ### idxd diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index 28b3d3871..002427537 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -657,6 +657,24 @@ typedef void (*spdk_nvme_attach_cb)(void *cb_ctx, const struct spdk_nvme_transpo */ typedef void (*spdk_nvme_remove_cb)(void *cb_ctx, struct spdk_nvme_ctrlr *ctrlr); +typedef bool (*spdk_nvme_pcie_hotplug_filter_cb)(const struct spdk_pci_addr *addr); + +/** + * Register the associated function to allow filtering of hot-inserted PCIe SSDs. + * + * If an application is using spdk_nvme_probe() to detect hot-inserted SSDs, + * this function may be used to register a function to filter those SSDs. + * If the filter function returns true, the nvme library will notify the SPDK + * env layer to allow probing of the device. + * + * Registering a filter function is optional. If none is registered, the nvme + * library will allow probing of all hot-inserted SSDs. + * + * \param filter_cb Filter function callback routine + */ +void +spdk_nvme_pcie_set_hotplug_filter(spdk_nvme_pcie_hotplug_filter_cb filter_cb); + /** * Enumerate the bus indicated by the transport ID and attach the userspace NVMe * driver to each device found if desired. diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index 27fc6bbdd..4eb9c7c4f 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -55,6 +55,7 @@ static int nvme_pcie_ctrlr_attach(struct spdk_nvme_probe_ctx *probe_ctx, static uint16_t g_signal_lock; static bool g_sigset = false; +static spdk_nvme_pcie_hotplug_filter_cb g_hotplug_filter_cb; static void nvme_sigbus_fault_sighandler(int signum, siginfo_t *info, void *ctx) @@ -115,7 +116,10 @@ _nvme_pcie_hotplug_monitor(struct spdk_nvme_probe_ctx *probe_ctx) SPDK_DEBUGLOG(nvme, "add nvme address: %s\n", event.traddr); if (spdk_process_is_primary()) { - if (!spdk_pci_addr_parse(&pci_addr, event.traddr)) { + if (spdk_pci_addr_parse(&pci_addr, event.traddr) != 0) { + continue; + } + if (g_hotplug_filter_cb == NULL || g_hotplug_filter_cb(&pci_addr)) { nvme_pcie_ctrlr_attach(probe_ctx, &pci_addr); } } @@ -598,6 +602,7 @@ nvme_pcie_ctrlr_attach(struct spdk_nvme_probe_ctx *probe_ctx, struct spdk_pci_ad enum_ctx.has_pci_addr = true; enum_ctx.pci_addr = *pci_addr; + spdk_pci_device_allow(pci_addr); return spdk_pci_enumerate(spdk_pci_nvme_get_driver(), pcie_nvme_enum_cb, &enum_ctx); } @@ -1288,6 +1293,12 @@ exit: return rc; } +void +spdk_nvme_pcie_set_hotplug_filter(spdk_nvme_pcie_hotplug_filter_cb filter_cb) +{ + g_hotplug_filter_cb = filter_cb; +} + static struct spdk_pci_id nvme_pci_driver_id[] = { { .class_id = SPDK_PCI_CLASS_NVME, diff --git a/lib/nvme/spdk_nvme.map b/lib/nvme/spdk_nvme.map index 033464365..d2455748b 100644 --- a/lib/nvme/spdk_nvme.map +++ b/lib/nvme/spdk_nvme.map @@ -27,6 +27,8 @@ spdk_nvme_detach_async; spdk_nvme_detach_poll_async; + spdk_nvme_pcie_set_hotplug_filter; + spdk_nvme_ctrlr_is_discovery; spdk_nvme_ctrlr_get_default_ctrlr_opts; spdk_nvme_ctrlr_set_trid; diff --git a/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c b/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c index 5a0aca62c..3ab986fb7 100644 --- a/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c +++ b/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c @@ -67,6 +67,7 @@ DEFINE_STUB(spdk_pci_device_attach, int, (struct spdk_pci_driver *driver, spdk_p DEFINE_STUB(spdk_pci_device_claim, int, (struct spdk_pci_device *dev), 0); DEFINE_STUB_V(spdk_pci_device_unclaim, (struct spdk_pci_device *dev)); DEFINE_STUB_V(spdk_pci_device_detach, (struct spdk_pci_device *device)); +DEFINE_STUB(spdk_pci_device_allow, int, (struct spdk_pci_addr *pci_addr), 0); DEFINE_STUB(spdk_pci_device_cfg_write16, int, (struct spdk_pci_device *dev, uint16_t value, uint32_t offset), 0); DEFINE_STUB(spdk_pci_device_cfg_read16, int, (struct spdk_pci_device *dev, uint16_t *value,