From 92bf76c9a993dc5aff8d903860a672de6890240e Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Fri, 14 Sep 2018 02:20:55 -0400 Subject: [PATCH] nvme: make identify ns can be executed asynchronously Change-Id: I189ad8889c74937bf43bcf2c3029416ddb94976d Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/425705 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Ben Walker Reviewed-by: Xiaodong Liu Reviewed-by: Paul Luse Reviewed-by: GangCao --- lib/nvme/nvme_ctrlr.c | 83 +++++++++++++++---- lib/nvme/nvme_internal.h | 7 +- lib/nvme/nvme_ns.c | 10 ++- .../lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c | 1 + 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 7a93d2ff1..072c55b72 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -40,6 +40,7 @@ static int nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr, struct nvme_async_event_request *aer); +static int nvme_ctrlr_identify_ns_async(struct spdk_nvme_ns *ns); static int nvme_ctrlr_get_cc(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cc_register *cc) @@ -636,6 +637,8 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state) return "identify active ns"; case NVME_CTRLR_STATE_IDENTIFY_NS: return "identify ns"; + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS: + return "wait for identify ns"; case NVME_CTRLR_STATE_IDENTIFY_ID_DESCS: return "identify id descriptor"; case NVME_CTRLR_STATE_CONFIGURE_AER: @@ -962,6 +965,51 @@ fail: return rc; } +static void +nvme_ctrlr_identify_ns_async_done(void *arg, const struct spdk_nvme_cpl *cpl) +{ + struct spdk_nvme_ns *ns = (struct spdk_nvme_ns *)arg; + struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr; + uint32_t nsid; + int rc; + + if (spdk_nvme_cpl_is_error(cpl)) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + return; + } else { + nvme_ns_set_identify_data(ns); + } + + /* move on to the next active NS */ + nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, ns->id); + ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); + if (ns == NULL) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_IDENTIFY_ID_DESCS, NVME_TIMEOUT_INFINITE); + return; + } + ns->ctrlr = ctrlr; + ns->id = nsid; + + rc = nvme_ctrlr_identify_ns_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } +} + +static int +nvme_ctrlr_identify_ns_async(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr; + struct spdk_nvme_ns_data *nsdata; + + nsdata = &ctrlr->nsdata[ns->id - 1]; + + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS, NVME_TIMEOUT_INFINITE); + return nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS, 0, ns->id, + nsdata, sizeof(*nsdata), + nvme_ctrlr_identify_ns_async_done, ns); +} + static int nvme_ctrlr_identify_namespaces(struct spdk_nvme_ctrlr *ctrlr) { @@ -969,23 +1017,23 @@ nvme_ctrlr_identify_namespaces(struct spdk_nvme_ctrlr *ctrlr) struct spdk_nvme_ns *ns; int rc; - for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); - nsid != 0; nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) { - ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); - if (ns == NULL) { - continue; - } - - ns->ctrlr = ctrlr; - ns->id = nsid; - - rc = nvme_ctrlr_identify_ns(ns); - if (rc < 0) { - return rc; - } + nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); + ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); + if (ns == NULL) { + /* No active NS, move on to the next state */ + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return 0; } - return 0; + ns->ctrlr = ctrlr; + ns->id = nsid; + + rc = nvme_ctrlr_identify_ns_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } + + return rc; } static int @@ -1893,7 +1941,10 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) case NVME_CTRLR_STATE_IDENTIFY_NS: rc = nvme_ctrlr_identify_namespaces(ctrlr); - nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_IDENTIFY_ID_DESCS, NVME_TIMEOUT_INFINITE); + break; + + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS: + spdk_nvme_qpair_process_completions(ctrlr->adminq, 0); break; case NVME_CTRLR_STATE_IDENTIFY_ID_DESCS: diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index fe9c7142c..c2c851c1d 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -463,6 +463,11 @@ enum nvme_ctrlr_state { */ NVME_CTRLR_STATE_IDENTIFY_NS, + /** + * Waiting for the Identify Namespace commands to be completed. + */ + NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS, + /** * Get Identify Namespace Identification Descriptor. */ @@ -802,8 +807,8 @@ int nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req); int nvme_ctrlr_identify_active_ns(struct spdk_nvme_ctrlr *ctrlr); -int nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns); int nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns); +void nvme_ns_set_identify_data(struct spdk_nvme_ns *ns); int nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id, struct spdk_nvme_ctrlr *ctrlr); void nvme_ns_destruct(struct spdk_nvme_ns *ns); diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index d691e4b0d..799d2dfea 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -39,7 +39,13 @@ _nvme_ns_get_data(struct spdk_nvme_ns *ns) return &ns->ctrlr->nsdata[ns->id - 1]; } -static void +/** + * Update Namespace flags based on Identify Controller + * and Identify Namespace. This can be also used for + * Namespace Attribute Notice events and Namespace + * operations such as Attach/Detach. + */ +void nvme_ns_set_identify_data(struct spdk_nvme_ns *ns) { struct spdk_nvme_ns_data *nsdata; @@ -96,7 +102,7 @@ nvme_ns_set_identify_data(struct spdk_nvme_ns *ns) } } -int +static int nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns) { struct nvme_completion_poll_status status; diff --git a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c index 4ff0111d7..db7469ff0 100644 --- a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c +++ b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c @@ -68,6 +68,7 @@ DEFINE_STUB(nvme_ctrlr_cmd_set_host_id, int, spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); DEFINE_STUB(nvme_ctrlr_identify_ns, int, (struct spdk_nvme_ns *ns), 0); DEFINE_STUB(nvme_ctrlr_identify_id_desc, int, (struct spdk_nvme_ns *ns), 0); +DEFINE_STUB_V(nvme_ns_set_identify_data, (struct spdk_nvme_ns *ns)); struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_transport_id *trid, const struct spdk_nvme_ctrlr_opts *opts,