From a2fdc4dd73ed4710cacd508f06344b1639386f40 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 9 Oct 2018 22:17:46 -0400 Subject: [PATCH] nvme: make identify NS id descriptors can be executed asynchronously With Identify Namespace Identification Descriptors can be executed asynchronously, most of functions in the controller initialization now can be executed asynchronously now, for host with multiple controllers this can save some time during initialization. Change-Id: I70e3c6c2c691134d2ae4c5969288cced1538c6cc Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/428585 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: GangCao Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/nvme/nvme_ctrlr.c | 79 ++++++++++++++++++++++++++++++++++------ lib/nvme/nvme_internal.h | 9 ++++- lib/nvme/nvme_ns.c | 2 +- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 072c55b72..7a1674e4f 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -41,6 +41,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_identify_id_desc_async(struct spdk_nvme_ns *ns); static int nvme_ctrlr_get_cc(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cc_register *cc) @@ -640,7 +641,9 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state) case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS: return "wait for identify ns"; case NVME_CTRLR_STATE_IDENTIFY_ID_DESCS: - return "identify id descriptor"; + return "identify namespace id descriptors"; + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS: + return "wait for identify namespace id descriptors"; case NVME_CTRLR_STATE_CONFIGURE_AER: return "configure AER"; case NVME_CTRLR_STATE_WAIT_FOR_CONFIGURE_AER: @@ -1036,6 +1039,46 @@ nvme_ctrlr_identify_namespaces(struct spdk_nvme_ctrlr *ctrlr) return rc; } +static void +nvme_ctrlr_identify_id_desc_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_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return; + } + + /* 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_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return; + } + + rc = nvme_ctrlr_identify_id_desc_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } +} + +static int +nvme_ctrlr_identify_id_desc_async(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr; + + memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list)); + + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS, NVME_TIMEOUT_INFINITE); + return nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST, + 0, ns->id, ns->id_desc_list, sizeof(ns->id_desc_list), + nvme_ctrlr_identify_id_desc_async_done, ns); +} + static int nvme_ctrlr_identify_id_desc_namespaces(struct spdk_nvme_ctrlr *ctrlr) { @@ -1043,19 +1086,27 @@ nvme_ctrlr_identify_id_desc_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; - } - rc = nvme_ctrlr_identify_id_desc(ns); - if (rc < 0) { - return rc; - } + if (ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) || + (ctrlr->quirks & NVME_QUIRK_IDENTIFY_CNS)) { + SPDK_DEBUGLOG(SPDK_LOG_NVME, "Version < 1.3; not attempting to retrieve NS ID Descriptor List\n"); + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return 0; } - return 0; + 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; + } + + rc = nvme_ctrlr_identify_id_desc_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } + + return rc; } static void @@ -1952,6 +2003,10 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); break; + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS: + spdk_nvme_qpair_process_completions(ctrlr->adminq, 0); + break; + case NVME_CTRLR_STATE_CONFIGURE_AER: rc = nvme_ctrlr_configure_aer(ctrlr); break; diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index c2c851c1d..10dc08ab6 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -469,10 +469,16 @@ enum nvme_ctrlr_state { NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS, /** - * Get Identify Namespace Identification Descriptor. + * Get Identify Namespace Identification Descriptors. */ NVME_CTRLR_STATE_IDENTIFY_ID_DESCS, + /** + * Waiting for the Identify Namespace Identification + * Descriptors to be completed. + */ + NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS, + /** * Configure AER of the controller. */ @@ -807,7 +813,6 @@ 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_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); diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 799d2dfea..b88bf1746 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -130,7 +130,7 @@ nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns) return 0; } -int +static int nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns) { struct nvme_completion_poll_status status;