From be1c82b7a81933af29ec5525489a4054c7bf489c Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Wed, 18 Apr 2018 21:52:55 -0400 Subject: [PATCH] nvme: update the NS identify data according to AER Number of Namespaces of controller identify structure defines the maximum number of namespaces supported by this controller, for physical NVMe controllers, the NN is a fixed number, while here, we set the same rule for NVMeoF controllers. After NVMe driver got namespace notice event, it should update the namespace identify data structure for NS attach/detach commands. Change-Id: Id72a2600a2ce9492fa2d6e09924667acbb77ae43 Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/412883 Tested-by: SPDK Automated Test System Reviewed-by: Shuhei Matsumoto Reviewed-by: Daniel Verkamp Reviewed-by: Jim Harris --- lib/nvme/nvme_ctrlr.c | 50 ++++++++++++++++++++++++++++++++----------- lib/nvme/nvme_ns.c | 23 +++++++++++++------- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 02f6da5f8..cd19f9adf 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -1065,9 +1065,38 @@ nvme_ctrlr_destruct_namespaces(struct spdk_nvme_ctrlr *ctrlr) } static int -nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) +nvme_ctrlr_update_namespaces(struct spdk_nvme_ctrlr *ctrlr) { uint32_t i, nn = ctrlr->cdata.nn; + struct spdk_nvme_ns_data *nsdata; + + if (nvme_ctrlr_identify_active_ns(ctrlr)) { + return -1; + } + + for (i = 0; i < nn; i++) { + struct spdk_nvme_ns *ns = &ctrlr->ns[i]; + uint32_t nsid = i + 1; + nsdata = &ctrlr->nsdata[nsid - 1]; + + if ((nsdata->ncap == 0) && spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { + if (nvme_ns_construct(ns, nsid, ctrlr) != 0) { + continue; + } + } + + if (nsdata->ncap && !spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { + nvme_ns_destruct(ns); + } + } + + return 0; +} + +static int +nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) +{ + uint32_t nn = ctrlr->cdata.nn; uint64_t phys_addr = 0; /* ctrlr->num_ns may be 0 (startup) or a different number of namespaces (reset), @@ -1096,19 +1125,9 @@ nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) ctrlr->num_ns = nn; } - if (nvme_ctrlr_identify_active_ns(ctrlr)) { + if (nvme_ctrlr_update_namespaces(ctrlr)) { goto fail; } - - for (i = 0; i < nn; i++) { - struct spdk_nvme_ns *ns = &ctrlr->ns[i]; - uint32_t nsid = i + 1; - - if (nvme_ns_construct(ns, nsid, ctrlr) != 0) { - goto fail; - } - } - return 0; fail: @@ -1122,6 +1141,7 @@ nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl) struct nvme_async_event_request *aer = arg; struct spdk_nvme_ctrlr *ctrlr = aer->ctrlr; struct spdk_nvme_ctrlr_process *active_proc; + union spdk_nvme_async_event_completion event; if (cpl->status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION) { /* @@ -1133,6 +1153,12 @@ nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl) return; } + event.raw = cpl->cdw0; + if ((event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) && + (event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED)) { + nvme_ctrlr_update_namespaces(ctrlr); + } + active_proc = spdk_nvme_ctrlr_get_current_process(ctrlr); if (active_proc && active_proc->aer_cb_fn) { active_proc->aer_cb_fn(active_proc->aer_cb_arg, cpl); diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 41cc13a74..e61b3700c 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -58,14 +58,7 @@ int nvme_ns_identify_update(struct spdk_nvme_ns *ns) &ns->ctrlr->ctrlr_lock)) { /* This can occur if the namespace is not active. Simply zero the * namespace data and continue. */ - memset(nsdata, 0, sizeof(*nsdata)); - ns->sector_size = 0; - ns->extended_lba_size = 0; - ns->md_size = 0; - ns->pi_type = 0; - ns->sectors_per_max_io = 0; - ns->sectors_per_stripe = 0; - ns->flags = 0; + nvme_ns_destruct(ns); return 0; } @@ -300,5 +293,19 @@ int nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id, void nvme_ns_destruct(struct spdk_nvme_ns *ns) { + struct spdk_nvme_ns_data *nsdata; + if (!ns->id) { + return; + } + + nsdata = _nvme_ns_get_data(ns); + memset(nsdata, 0, sizeof(*nsdata)); + ns->sector_size = 0; + ns->extended_lba_size = 0; + ns->md_size = 0; + ns->pi_type = 0; + ns->sectors_per_max_io = 0; + ns->sectors_per_stripe = 0; + ns->flags = 0; }