nvme: introduce probe context data structure and API

Existing NVMe driver uses a global list g_nvme_init_ctrlrs
to track the controllers during initialization, and internal
function will start each controller in the list one by one
until the list is empty.  We introduce a probe context
and move the global list into the context, with the context
we can enable asynchronous probe API in the next patch, also
this can enable parallel probe feature.

Change-Id: I538537abe8c1a4a82fb168ca8055de42caa6e4f9
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/426304
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Changpeng Liu 2019-01-28 04:16:47 -05:00
parent 207353960f
commit 3306e49e24
12 changed files with 164 additions and 144 deletions

View File

@ -566,6 +566,40 @@ struct spdk_nvme_ctrlr *spdk_nvme_connect(const struct spdk_nvme_transport_id *t
const struct spdk_nvme_ctrlr_opts *opts,
size_t opts_size);
struct spdk_nvme_probe_ctx {
struct spdk_nvme_transport_id trid;
void *cb_ctx;
spdk_nvme_probe_cb probe_cb;
spdk_nvme_attach_cb attach_cb;
spdk_nvme_remove_cb remove_cb;
TAILQ_HEAD(, spdk_nvme_ctrlr) init_ctrlrs;
};
/**
* Initialize a context to track the probe result based on transport ID.
*
* \param probe_ctx Context used to track probe actions.
* \param trid The transport ID indicating which bus to enumerate. If the trtype
* is PCIe or trid is NULL, this will scan the local PCIe bus. If the trtype is
* RDMA, the traddr and trsvcid must point at the location of an NVMe-oF discovery
* service.
* \param cb_ctx Opaque value which will be passed back in cb_ctx parameter of
* the callbacks.
* \param probe_cb will be called once per NVMe device found in the system.
* \param attach_cb will be called for devices for which probe_cb returned true
* once that NVMe controller has been attached to the userspace driver.
* \param remove_cb will be called for devices that were attached in a previous
* spdk_nvme_probe() call but are no longer attached to the system. Optional;
* specify NULL if removal notices are not desired.
*
*/
void spdk_nvme_probe_ctx_init(struct spdk_nvme_probe_ctx *probe_ctx,
const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_attach_cb attach_cb,
spdk_nvme_remove_cb remove_cb);
/**
* Detach specified device returned by spdk_nvme_probe()'s attach_cb from the
* NVMe driver.

View File

@ -44,9 +44,6 @@ int32_t spdk_nvme_retry_count;
/* gross timeout of 180 seconds in milliseconds */
static int g_nvme_driver_timeout_ms = 3 * 60 * 1000;
static TAILQ_HEAD(, spdk_nvme_ctrlr) g_nvme_init_ctrlrs =
TAILQ_HEAD_INITIALIZER(g_nvme_init_ctrlrs);
/* Per-process attached controller list */
static TAILQ_HEAD(, spdk_nvme_ctrlr) g_nvme_attached_ctrlrs =
TAILQ_HEAD_INITIALIZER(g_nvme_attached_ctrlrs);
@ -58,11 +55,11 @@ nvme_ctrlr_shared(const struct spdk_nvme_ctrlr *ctrlr)
return ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE;
}
/* Caller must hold g_spdk_nvme_driver->lock */
void
nvme_ctrlr_connected(struct spdk_nvme_ctrlr *ctrlr)
nvme_ctrlr_connected(struct spdk_nvme_probe_ctx *probe_ctx,
struct spdk_nvme_ctrlr *ctrlr)
{
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, ctrlr, tailq);
TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq);
}
int
@ -396,8 +393,8 @@ nvme_driver_init(void)
}
int
nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, void *devhandle,
spdk_nvme_probe_cb probe_cb, void *cb_ctx)
nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle)
{
struct spdk_nvme_ctrlr *ctrlr;
struct spdk_nvme_ctrlr_opts opts;
@ -406,14 +403,14 @@ nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, void *devhandle,
spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts));
if (!probe_cb || probe_cb(cb_ctx, trid, &opts)) {
if (!probe_ctx->probe_cb || probe_ctx->probe_cb(probe_ctx->cb_ctx, trid, &opts)) {
ctrlr = nvme_transport_ctrlr_construct(trid, &opts, devhandle);
if (ctrlr == NULL) {
SPDK_ERRLOG("Failed to construct NVMe controller for SSD: %s\n", trid->traddr);
return -1;
}
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, ctrlr, tailq);
TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq);
return 0;
}
@ -421,26 +418,22 @@ nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, void *devhandle,
}
static int
nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, void *cb_ctx,
spdk_nvme_attach_cb attach_cb)
nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_probe_ctx *probe_ctx)
{
int rc = 0;
rc = nvme_ctrlr_process_init(ctrlr);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
if (rc) {
/* Controller failed to initialize. */
TAILQ_REMOVE(&g_nvme_init_ctrlrs, ctrlr, tailq);
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq);
SPDK_ERRLOG("Failed to initialize SSD: %s\n", ctrlr->trid.traddr);
nvme_ctrlr_destruct(ctrlr);
return rc;
}
if (ctrlr->state != NVME_CTRLR_STATE_READY) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
return 0;
}
@ -448,7 +441,9 @@ nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, void *cb_ctx,
* Controller has been initialized.
* Move it to the attached_ctrlrs list.
*/
TAILQ_REMOVE(&g_nvme_init_ctrlrs, ctrlr, tailq);
TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
if (nvme_ctrlr_shared(ctrlr)) {
TAILQ_INSERT_TAIL(&g_spdk_nvme_driver->shared_attached_ctrlrs, ctrlr, tailq);
} else {
@ -460,44 +455,36 @@ nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, void *cb_ctx,
* call nvme_detach() immediately.
*/
nvme_ctrlr_proc_get_ref(ctrlr);
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
/*
* Unlock while calling attach_cb() so the user can call other functions
* that may take the driver lock, like nvme_detach().
*/
if (attach_cb) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
attach_cb(cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts);
if (probe_ctx->attach_cb) {
probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts);
return 0;
}
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
return 0;
}
static int
nvme_init_controllers(void *cb_ctx, spdk_nvme_attach_cb attach_cb)
nvme_init_controllers(struct spdk_nvme_probe_ctx *probe_ctx)
{
int rc = 0;
struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp;
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
/* Initialize all new controllers in the g_nvme_init_ctrlrs list in parallel. */
while (!TAILQ_EMPTY(&g_nvme_init_ctrlrs)) {
TAILQ_FOREACH_SAFE(ctrlr, &g_nvme_init_ctrlrs, tailq, ctrlr_tmp) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
rc = nvme_ctrlr_poll_internal(ctrlr, cb_ctx, attach_cb);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
/* Initialize all new controllers in the probe context init_ctrlrs list in parallel. */
while (!TAILQ_EMPTY(&probe_ctx->init_ctrlrs)) {
TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) {
rc = nvme_ctrlr_poll_internal(ctrlr, probe_ctx);
if (rc) {
break;
}
}
}
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
g_spdk_nvme_driver->initialized = true;
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
return rc;
}
@ -539,21 +526,20 @@ spdk_nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid)
/* This function must only be called while holding g_spdk_nvme_driver->lock */
static int
spdk_nvme_probe_internal(const struct spdk_nvme_transport_id *trid, void *cb_ctx,
spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb attach_cb,
spdk_nvme_remove_cb remove_cb, bool direct_connect)
spdk_nvme_probe_internal(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
int rc;
struct spdk_nvme_ctrlr *ctrlr;
if (!spdk_nvme_transport_available(trid->trtype)) {
SPDK_ERRLOG("NVMe trtype %u not available\n", trid->trtype);
if (!spdk_nvme_transport_available(probe_ctx->trid.trtype)) {
SPDK_ERRLOG("NVMe trtype %u not available\n", probe_ctx->trid.trtype);
return -1;
}
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
rc = nvme_transport_ctrlr_scan(trid, cb_ctx, probe_cb, remove_cb, direct_connect);
rc = nvme_transport_ctrlr_scan(probe_ctx, direct_connect);
if (rc != 0) {
SPDK_ERRLOG("NVMe ctrlr scan failed\n");
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
@ -563,11 +549,11 @@ spdk_nvme_probe_internal(const struct spdk_nvme_transport_id *trid, void *cb_ctx
/*
* Probe controllers on the shared_attached_ctrlrs list
*/
if (!spdk_process_is_primary() && (trid->trtype == SPDK_NVME_TRANSPORT_PCIE)) {
if (!spdk_process_is_primary() && (probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE)) {
TAILQ_FOREACH(ctrlr, &g_spdk_nvme_driver->shared_attached_ctrlrs, tailq) {
/* Do not attach other ctrlrs if user specify a valid trid */
if ((strlen(trid->traddr) != 0) &&
(spdk_nvme_transport_id_compare(trid, &ctrlr->trid))) {
if ((strlen(probe_ctx->trid.traddr) != 0) &&
(spdk_nvme_transport_id_compare(&probe_ctx->trid, &ctrlr->trid))) {
continue;
}
@ -582,9 +568,9 @@ spdk_nvme_probe_internal(const struct spdk_nvme_transport_id *trid, void *cb_ctx
* Unlock while calling attach_cb() so the user can call other functions
* that may take the driver lock, like nvme_detach().
*/
if (attach_cb) {
if (probe_ctx->attach_cb) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
attach_cb(cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts);
probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
}
}
@ -602,6 +588,7 @@ spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx,
{
int rc;
struct spdk_nvme_transport_id trid_pcie;
struct spdk_nvme_probe_ctx probe_ctx;
rc = nvme_driver_init();
if (rc != 0) {
@ -614,7 +601,8 @@ spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx,
trid = &trid_pcie;
}
rc = spdk_nvme_probe_internal(trid, cb_ctx, probe_cb, attach_cb, remove_cb, false);
spdk_nvme_probe_ctx_init(&probe_ctx, trid, cb_ctx, probe_cb, attach_cb, remove_cb);
rc = spdk_nvme_probe_internal(&probe_ctx, false);
if (rc != 0) {
return rc;
}
@ -625,7 +613,7 @@ spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx,
* but maintain the value of rc to signal errors when we return.
*/
rc = nvme_init_controllers(cb_ctx, attach_cb);
rc = nvme_init_controllers(&probe_ctx);
}
return rc;
@ -655,6 +643,7 @@ spdk_nvme_connect(const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_ctrlr_connect_opts *user_connect_opts = NULL;
struct spdk_nvme_ctrlr *ctrlr = NULL;
spdk_nvme_probe_cb probe_cb = NULL;
struct spdk_nvme_probe_ctx probe_ctx;
if (trid == NULL) {
SPDK_ERRLOG("No transport ID specified\n");
@ -673,10 +662,11 @@ spdk_nvme_connect(const struct spdk_nvme_transport_id *trid,
probe_cb = spdk_nvme_connect_probe_cb;
}
spdk_nvme_probe_internal(trid, user_connect_opts, probe_cb, NULL, NULL, true);
spdk_nvme_probe_ctx_init(&probe_ctx, trid, user_connect_opts, probe_cb, NULL, NULL);
spdk_nvme_probe_internal(&probe_ctx, true);
if (spdk_process_is_primary() || trid->trtype != SPDK_NVME_TRANSPORT_PCIE) {
rc = nvme_init_controllers(NULL, NULL);
rc = nvme_init_controllers(&probe_ctx);
if (rc != 0) {
return NULL;
}
@ -1059,4 +1049,20 @@ spdk_nvme_prchk_flags_str(uint32_t prchk_flags)
}
}
void
spdk_nvme_probe_ctx_init(struct spdk_nvme_probe_ctx *probe_ctx,
const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_attach_cb attach_cb,
spdk_nvme_remove_cb remove_cb)
{
probe_ctx->trid = *trid;
probe_ctx->cb_ctx = cb_ctx;
probe_ctx->probe_cb = probe_cb;
probe_ctx->attach_cb = attach_cb;
probe_ctx->remove_cb = remove_cb;
TAILQ_INIT(&probe_ctx->init_ctrlrs);
}
SPDK_LOG_REGISTER_COMPONENT("nvme", SPDK_LOG_NVME)

View File

@ -143,7 +143,7 @@ nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint
static void
nvme_fabric_discover_probe(struct spdk_nvmf_discovery_log_page_entry *entry,
void *cb_ctx, spdk_nvme_probe_cb probe_cb)
struct spdk_nvme_probe_ctx *probe_ctx)
{
struct spdk_nvme_transport_id trid;
uint8_t *end;
@ -196,7 +196,7 @@ nvme_fabric_discover_probe(struct spdk_nvmf_discovery_log_page_entry *entry,
trid.subnqn, trid.trtype,
trid.traddr, trid.trsvcid);
nvme_ctrlr_probe(&trid, NULL, probe_cb, cb_ctx);
nvme_ctrlr_probe(&trid, probe_ctx, NULL);
}
static int
@ -221,7 +221,7 @@ nvme_fabric_get_discovery_log_page(struct spdk_nvme_ctrlr *ctrlr,
int
nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,
void *cb_ctx, spdk_nvme_probe_cb probe_cb)
struct spdk_nvme_probe_ctx *probe_ctx)
{
struct spdk_nvmf_discovery_log_page *log_page;
struct spdk_nvmf_discovery_log_page_entry *log_page_entry;
@ -260,7 +260,7 @@ nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,
}
for (i = 0; i < numrec; i++) {
nvme_fabric_discover_probe(log_page_entry++, cb_ctx, probe_cb);
nvme_fabric_discover_probe(log_page_entry++, probe_ctx);
}
remaining_num_rec -= numrec;
log_page_offset += numrec * sizeof(struct spdk_nvmf_discovery_log_page_entry);

View File

@ -804,15 +804,16 @@ int nvme_ctrlr_add_process(struct spdk_nvme_ctrlr *ctrlr, void *devhandle);
void nvme_ctrlr_free_processes(struct spdk_nvme_ctrlr *ctrlr);
struct spdk_pci_device *nvme_ctrlr_proc_get_devhandle(struct spdk_nvme_ctrlr *ctrlr);
int nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, void *devhandle,
spdk_nvme_probe_cb probe_cb, void *cb_ctx);
int nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle);
int nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr);
void nvme_ctrlr_destruct_finish(struct spdk_nvme_ctrlr *ctrlr);
void nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr);
void nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr, bool hot_remove);
int nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr);
void nvme_ctrlr_connected(struct spdk_nvme_ctrlr *ctrlr);
void nvme_ctrlr_connected(struct spdk_nvme_probe_ctx *probe_ctx,
struct spdk_nvme_ctrlr *ctrlr);
int nvme_ctrlr_submit_admin_request(struct spdk_nvme_ctrlr *ctrlr,
struct nvme_request *req);
@ -841,8 +842,8 @@ int nvme_fabric_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset,
int nvme_fabric_ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value);
int nvme_fabric_ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value);
int nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value);
int nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr, void *cb_ctx,
spdk_nvme_probe_cb probe_cb);
int nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_probe_ctx *probe_ctx);
int nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries);
static inline struct nvme_request *
@ -970,7 +971,7 @@ struct spdk_nvme_ctrlr *spdk_nvme_get_ctrlr_by_trid_unsafe(
struct spdk_nvme_ctrlr *nvme_ ## name ## _ctrlr_construct(const struct spdk_nvme_transport_id *trid, const struct spdk_nvme_ctrlr_opts *opts, \
void *devhandle); \
int nvme_ ## name ## _ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr); \
int nvme_ ## name ## _ctrlr_scan(const struct spdk_nvme_transport_id *trid, void *cb_ctx, spdk_nvme_probe_cb probe_cb, spdk_nvme_remove_cb remove_cb, bool direct_connect); \
int nvme_ ## name ## _ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx, bool direct_connect); \
int nvme_ ## name ## _ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr); \
int nvme_ ## name ## _ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value); \
int nvme_ ## name ## _ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value); \

View File

@ -60,8 +60,7 @@
#define NVME_MAX_PRP_LIST_ENTRIES (506)
struct nvme_pcie_enum_ctx {
spdk_nvme_probe_cb probe_cb;
void *cb_ctx;
struct spdk_nvme_probe_ctx *probe_ctx;
struct spdk_pci_addr pci_addr;
bool has_pci_addr;
};
@ -197,7 +196,7 @@ struct nvme_pcie_qpair {
uint64_t cpl_bus_addr;
};
static int nvme_pcie_ctrlr_attach(spdk_nvme_probe_cb probe_cb, void *cb_ctx,
static int nvme_pcie_ctrlr_attach(struct spdk_nvme_probe_ctx *probe_ctx,
struct spdk_pci_addr *pci_addr);
static int nvme_pcie_qpair_construct(struct spdk_nvme_qpair *qpair);
static int nvme_pcie_qpair_destroy(struct spdk_nvme_qpair *qpair);
@ -247,8 +246,7 @@ nvme_pcie_ctrlr_setup_signal(void)
}
static int
_nvme_pcie_hotplug_monitor(void *cb_ctx, spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb)
_nvme_pcie_hotplug_monitor(struct spdk_nvme_probe_ctx *probe_ctx)
{
struct spdk_nvme_ctrlr *ctrlr, *tmp;
struct spdk_uevent event;
@ -264,7 +262,7 @@ _nvme_pcie_hotplug_monitor(void *cb_ctx, spdk_nvme_probe_cb probe_cb,
event.traddr);
if (spdk_process_is_primary()) {
if (!spdk_pci_addr_parse(&pci_addr, event.traddr)) {
nvme_pcie_ctrlr_attach(probe_cb, cb_ctx, &pci_addr);
nvme_pcie_ctrlr_attach(probe_ctx, &pci_addr);
}
}
} else if (event.action == SPDK_NVME_UEVENT_REMOVE) {
@ -284,9 +282,9 @@ _nvme_pcie_hotplug_monitor(void *cb_ctx, spdk_nvme_probe_cb probe_cb,
nvme_ctrlr_fail(ctrlr, true);
/* get the user app to clean up and stop I/O */
if (remove_cb) {
if (probe_ctx->remove_cb) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
remove_cb(cb_ctx, ctrlr);
probe_ctx->remove_cb(probe_ctx->cb_ctx, ctrlr);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
}
}
@ -301,9 +299,9 @@ _nvme_pcie_hotplug_monitor(void *cb_ctx, spdk_nvme_probe_cb probe_cb,
csts = spdk_nvme_ctrlr_get_regs_csts(ctrlr);
if (csts.raw == 0xffffffffU) {
nvme_ctrlr_fail(ctrlr, true);
if (remove_cb) {
if (probe_ctx->remove_cb) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
remove_cb(cb_ctx, ctrlr);
probe_ctx->remove_cb(probe_ctx->cb_ctx, ctrlr);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
}
}
@ -718,24 +716,19 @@ pcie_nvme_enum_cb(void *ctx, struct spdk_pci_device *pci_dev)
return 1;
}
return nvme_ctrlr_probe(&trid, pci_dev,
enum_ctx->probe_cb, enum_ctx->cb_ctx);
return nvme_ctrlr_probe(&trid, enum_ctx->probe_ctx, pci_dev);
}
int
nvme_pcie_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_pcie_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
struct nvme_pcie_enum_ctx enum_ctx = {};
enum_ctx.probe_cb = probe_cb;
enum_ctx.cb_ctx = cb_ctx;
enum_ctx.probe_ctx = probe_ctx;
if (strlen(trid->traddr) != 0) {
if (spdk_pci_addr_parse(&enum_ctx.pci_addr, trid->traddr)) {
if (strlen(probe_ctx->trid.traddr) != 0) {
if (spdk_pci_addr_parse(&enum_ctx.pci_addr, probe_ctx->trid.traddr)) {
return -1;
}
enum_ctx.has_pci_addr = true;
@ -747,7 +740,7 @@ nvme_pcie_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
SPDK_DEBUGLOG(SPDK_LOG_NVME, "Failed to open uevent netlink socket\n");
}
} else {
_nvme_pcie_hotplug_monitor(cb_ctx, probe_cb, remove_cb);
_nvme_pcie_hotplug_monitor(probe_ctx);
}
if (enum_ctx.has_pci_addr == false) {
@ -760,12 +753,11 @@ nvme_pcie_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
}
static int
nvme_pcie_ctrlr_attach(spdk_nvme_probe_cb probe_cb, void *cb_ctx, struct spdk_pci_addr *pci_addr)
nvme_pcie_ctrlr_attach(struct spdk_nvme_probe_ctx *probe_ctx, struct spdk_pci_addr *pci_addr)
{
struct nvme_pcie_enum_ctx enum_ctx;
enum_ctx.probe_cb = probe_cb;
enum_ctx.cb_ctx = cb_ctx;
enum_ctx.probe_ctx = probe_ctx;
enum_ctx.has_pci_addr = true;
enum_ctx.pci_addr = *pci_addr;

View File

@ -1344,10 +1344,7 @@ nvme_rdma_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
/* This function must only be called while holding g_spdk_nvme_driver->lock */
int
nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_rdma_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
struct spdk_nvme_ctrlr_opts discovery_opts;
@ -1356,9 +1353,9 @@ nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid,
int rc;
struct nvme_completion_poll_status status;
if (strcmp(discovery_trid->subnqn, SPDK_NVMF_DISCOVERY_NQN) != 0) {
if (strcmp(probe_ctx->trid.subnqn, SPDK_NVMF_DISCOVERY_NQN) != 0) {
/* It is not a discovery_ctrlr info and try to directly connect it */
rc = nvme_ctrlr_probe(discovery_trid, NULL, probe_cb, cb_ctx);
rc = nvme_ctrlr_probe(&probe_ctx->trid, probe_ctx, NULL);
return rc;
}
@ -1366,7 +1363,7 @@ nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid,
/* For discovery_ctrlr set the timeout to 0 */
discovery_opts.keep_alive_timeout_ms = 0;
discovery_ctrlr = nvme_rdma_ctrlr_construct(discovery_trid, &discovery_opts, NULL);
discovery_ctrlr = nvme_rdma_ctrlr_construct(&probe_ctx->trid, &discovery_opts, NULL);
if (discovery_ctrlr == NULL) {
return -1;
}
@ -1402,12 +1399,12 @@ nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid,
if (direct_connect == true) {
/* Set the ready state to skip the normal init process */
discovery_ctrlr->state = NVME_CTRLR_STATE_READY;
nvme_ctrlr_connected(discovery_ctrlr);
nvme_ctrlr_connected(probe_ctx, discovery_ctrlr);
nvme_ctrlr_add_process(discovery_ctrlr, 0);
return 0;
}
rc = nvme_fabric_ctrlr_discover(discovery_ctrlr, cb_ctx, probe_cb);
rc = nvme_fabric_ctrlr_discover(discovery_ctrlr, probe_ctx);
nvme_ctrlr_destruct(discovery_ctrlr);
return rc;
}

View File

@ -264,10 +264,7 @@ nvme_tcp_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
/* This function must only be called while holding g_spdk_nvme_driver->lock */
int
nvme_tcp_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_tcp_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
struct spdk_nvme_ctrlr_opts discovery_opts;
@ -276,9 +273,9 @@ nvme_tcp_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
int rc;
struct nvme_completion_poll_status status;
if (strcmp(trid->subnqn, SPDK_NVMF_DISCOVERY_NQN) != 0) {
if (strcmp(probe_ctx->trid.subnqn, SPDK_NVMF_DISCOVERY_NQN) != 0) {
/* Not a discovery controller - connect directly. */
rc = nvme_ctrlr_probe(trid, NULL, probe_cb, cb_ctx);
rc = nvme_ctrlr_probe(&probe_ctx->trid, probe_ctx, NULL);
return rc;
}
@ -286,7 +283,7 @@ nvme_tcp_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
/* For discovery_ctrlr set the timeout to 0 */
discovery_opts.keep_alive_timeout_ms = 0;
discovery_ctrlr = nvme_tcp_ctrlr_construct(trid, &discovery_opts, NULL);
discovery_ctrlr = nvme_tcp_ctrlr_construct(&probe_ctx->trid, &discovery_opts, NULL);
if (discovery_ctrlr == NULL) {
return -1;
}
@ -326,12 +323,12 @@ nvme_tcp_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
if (direct_connect == true) {
/* Set the ready state to skip the normal init process */
discovery_ctrlr->state = NVME_CTRLR_STATE_READY;
nvme_ctrlr_connected(discovery_ctrlr);
nvme_ctrlr_connected(probe_ctx, discovery_ctrlr);
nvme_ctrlr_add_process(discovery_ctrlr, 0);
return 0;
}
rc = nvme_fabric_ctrlr_discover(discovery_ctrlr, cb_ctx, probe_cb);
rc = nvme_fabric_ctrlr_discover(discovery_ctrlr, probe_ctx);
nvme_ctrlr_destruct(discovery_ctrlr);
SPDK_DEBUGLOG(SPDK_LOG_NVME, "leave\n");
return rc;

View File

@ -100,13 +100,10 @@ struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_tr
}
int
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
NVME_TRANSPORT_CALL(trid->trtype, ctrlr_scan, (trid, cb_ctx, probe_cb, remove_cb, direct_connect));
NVME_TRANSPORT_CALL(probe_ctx->trid.trtype, ctrlr_scan, (probe_ctx, direct_connect));
}
int

View File

@ -82,23 +82,20 @@ memset_trid(struct spdk_nvme_transport_id *trid1, struct spdk_nvme_transport_id
static bool ut_check_trtype = false;
int
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
struct spdk_nvme_ctrlr *ctrlr = NULL;
if (ut_check_trtype == true) {
CU_ASSERT(trid->trtype == SPDK_NVME_TRANSPORT_PCIE);
CU_ASSERT(probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE);
}
if (direct_connect == true && probe_cb) {
if (direct_connect == true && probe_ctx->probe_cb) {
nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock);
ctrlr = spdk_nvme_get_ctrlr_by_trid(trid);
ctrlr = spdk_nvme_get_ctrlr_by_trid(&probe_ctx->trid);
nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock);
probe_cb(cb_ctx, trid, &ctrlr->opts);
probe_ctx->probe_cb(probe_ctx->cb_ctx, &probe_ctx->trid, &ctrlr->opts);
}
return 0;
}
@ -162,7 +159,6 @@ test_spdk_nvme_probe(void)
/* driver init passes, transport available, we are primary */
MOCK_SET(spdk_process_is_primary, true);
TAILQ_INIT(&g_nvme_init_ctrlrs);
rc = spdk_nvme_probe(trid, cb_ctx, probe_cb, attach_cb, remove_cb);
CU_ASSERT(rc == 0);
@ -267,6 +263,7 @@ test_nvme_init_controllers(void)
struct nvme_driver test_driver;
void *cb_ctx = NULL;
spdk_nvme_attach_cb attach_cb = dummy_attach_cb;
struct spdk_nvme_probe_ctx probe_ctx;
struct spdk_nvme_ctrlr ctrlr;
pthread_mutexattr_t attr;
@ -275,8 +272,8 @@ test_nvme_init_controllers(void)
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
CU_ASSERT(pthread_mutexattr_init(&attr) == 0);
CU_ASSERT(pthread_mutex_init(&test_driver.lock, &attr) == 0);
TAILQ_INIT(&g_nvme_init_ctrlrs);
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, &ctrlr, tailq);
TAILQ_INIT(&probe_ctx.init_ctrlrs);
TAILQ_INSERT_TAIL(&probe_ctx.init_ctrlrs, &ctrlr, tailq);
TAILQ_INIT(&test_driver.shared_attached_ctrlrs);
/*
@ -286,10 +283,12 @@ test_nvme_init_controllers(void)
MOCK_SET(nvme_ctrlr_process_init, 1);
g_spdk_nvme_driver->initialized = false;
ut_destruct_called = false;
rc = nvme_init_controllers(cb_ctx, attach_cb);
probe_ctx.cb_ctx = cb_ctx;
probe_ctx.attach_cb = attach_cb;
rc = nvme_init_controllers(&probe_ctx);
CU_ASSERT(rc != 0);
CU_ASSERT(g_spdk_nvme_driver->initialized == true);
CU_ASSERT(TAILQ_EMPTY(&g_nvme_init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&probe_ctx.init_ctrlrs));
CU_ASSERT(ut_destruct_called == true);
/*
@ -297,13 +296,13 @@ test_nvme_init_controllers(void)
* forward by setting the ctrl state so that it can be moved
* the shared_attached_ctrlrs list.
*/
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, &ctrlr, tailq);
TAILQ_INSERT_TAIL(&probe_ctx.init_ctrlrs, &ctrlr, tailq);
ctrlr.state = NVME_CTRLR_STATE_READY;
MOCK_SET(nvme_ctrlr_process_init, 0);
rc = nvme_init_controllers(cb_ctx, attach_cb);
rc = nvme_init_controllers(&probe_ctx);
CU_ASSERT(rc == 0);
CU_ASSERT(ut_attach_cb_called == true);
CU_ASSERT(TAILQ_EMPTY(&g_nvme_init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&probe_ctx.init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs));
CU_ASSERT(TAILQ_FIRST(&g_spdk_nvme_driver->shared_attached_ctrlrs) == &ctrlr);
TAILQ_REMOVE(&g_spdk_nvme_driver->shared_attached_ctrlrs, &ctrlr, tailq);
@ -313,13 +312,13 @@ test_nvme_init_controllers(void)
*/
memset(&ctrlr, 0, sizeof(struct spdk_nvme_ctrlr));
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, &ctrlr, tailq);
TAILQ_INSERT_TAIL(&probe_ctx.init_ctrlrs, &ctrlr, tailq);
ctrlr.state = NVME_CTRLR_STATE_READY;
MOCK_SET(nvme_ctrlr_process_init, 0);
rc = nvme_init_controllers(cb_ctx, attach_cb);
rc = nvme_init_controllers(&probe_ctx);
CU_ASSERT(rc == 0);
CU_ASSERT(ut_attach_cb_called == true);
CU_ASSERT(TAILQ_EMPTY(&g_nvme_init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&probe_ctx.init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver->shared_attached_ctrlrs));
CU_ASSERT(TAILQ_FIRST(&g_nvme_attached_ctrlrs) == &ctrlr);
TAILQ_REMOVE(&g_nvme_attached_ctrlrs, &ctrlr, tailq);
@ -397,7 +396,6 @@ test_nvme_driver_init(void)
g_spdk_nvme_driver = NULL;
rc = nvme_driver_init();
CU_ASSERT(g_spdk_nvme_driver->initialized == false);
CU_ASSERT(TAILQ_EMPTY(&g_nvme_init_ctrlrs));
CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver->shared_attached_ctrlrs));
CU_ASSERT(rc == 0);
@ -706,19 +704,23 @@ test_nvme_ctrlr_probe(void)
int rc = 0;
struct spdk_nvme_ctrlr ctrlr = {};
const struct spdk_nvme_transport_id trid = {};
struct spdk_nvme_probe_ctx probe_ctx = {};
void *devhandle = NULL;
void *cb_ctx = NULL;
struct spdk_nvme_ctrlr *dummy = NULL;
/* test when probe_cb returns false */
MOCK_SET(dummy_probe_cb, false);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
spdk_nvme_probe_ctx_init(&probe_ctx, &trid, cb_ctx, dummy_probe_cb, NULL, NULL);
rc = nvme_ctrlr_probe(&trid, &probe_ctx, devhandle);
CU_ASSERT(rc == 1);
/* probe_cb returns true but we can't construct a ctrl */
MOCK_SET(dummy_probe_cb, true);
MOCK_SET(nvme_transport_ctrlr_construct, NULL);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
spdk_nvme_probe_ctx_init(&probe_ctx, &trid, cb_ctx, dummy_probe_cb, NULL, NULL);
rc = nvme_ctrlr_probe(&trid, &probe_ctx, devhandle);
CU_ASSERT(rc == -1);
/* happy path */
@ -726,12 +728,12 @@ test_nvme_ctrlr_probe(void)
SPDK_CU_ASSERT_FATAL(g_spdk_nvme_driver != NULL);
MOCK_SET(dummy_probe_cb, true);
MOCK_SET(nvme_transport_ctrlr_construct, &ctrlr);
TAILQ_INIT(&g_nvme_init_ctrlrs);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
spdk_nvme_probe_ctx_init(&probe_ctx, &trid, cb_ctx, dummy_probe_cb, NULL, NULL);
rc = nvme_ctrlr_probe(&trid, &probe_ctx, devhandle);
CU_ASSERT(rc == 0);
dummy = TAILQ_FIRST(&g_nvme_init_ctrlrs);
dummy = TAILQ_FIRST(&probe_ctx.init_ctrlrs);
CU_ASSERT(dummy == ut_nvme_transport_ctrlr_construct);
TAILQ_REMOVE(&g_nvme_init_ctrlrs, dummy, tailq);
TAILQ_REMOVE(&probe_ctx.init_ctrlrs, dummy, tailq);
MOCK_CLEAR_P(nvme_transport_ctrlr_construct);
free(g_spdk_nvme_driver);

View File

@ -168,10 +168,7 @@ nvme_ctrlr_get_ref_count(struct spdk_nvme_ctrlr *ctrlr)
}
int
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
return 0;

View File

@ -104,10 +104,7 @@ nvme_ctrlr_get_ref_count(struct spdk_nvme_ctrlr *ctrlr)
}
int
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
void *cb_ctx,
spdk_nvme_probe_cb probe_cb,
spdk_nvme_remove_cb remove_cb,
nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
bool direct_connect)
{
return 0;

View File

@ -197,8 +197,8 @@ nvme_ctrlr_proc_get_devhandle(struct spdk_nvme_ctrlr *ctrlr)
}
int
nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, void *devhandle,
spdk_nvme_probe_cb probe_cb, void *cb_ctx)
nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle)
{
abort();
}