nvme: add set_nvme_pcie_set_hotplug_filter

This function allows applications to specify whether
they wish to allow probing a newly attached NVMe
PCIe SSD.

The env layer will only even probe devices that have
been allowed.  By default, this is all devices, but
if the user has specified some list of
allowed PCI addresses (via spdk_env_opts pci_allowed)
then newly attached PCIe devices are implicitly not
allowed.  This API allows applications to add
device addresses to the allowed list after the
application has started.

This API will be useful for use cases where multiple
SPDK processes are running on one server, and assignment
of PCIe SSDs to those processes are based on some function
of the SSD's PCIe address.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I919bc267f2ad9130ab5c875ff760a301028b047e

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6184
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: <dongx.yi@intel.com>
This commit is contained in:
Jim Harris 2021-01-29 09:31:31 -07:00 committed by Tomasz Zawadzki
parent 207e05831f
commit e329ec45a6
5 changed files with 39 additions and 1 deletions

View File

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

View File

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

View File

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

View File

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

View File

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