From f7b58aea2b2f2e4531b00d57851ff4f187a838c9 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 24 Apr 2018 14:13:14 -0700 Subject: [PATCH] nvme: capture VS register at init time This will be used later instead of retrieving VS (potentially via a Get property command for Fabrics) multiple times. The Active NS List code was previously depending on the VER field of the Identify Controller data, but this was only added with NVMe 1.2, so we can't rely on it to detect NVMe 1.1 controllers; it is changed to use the new cache VS value instead. Change-Id: Iba9ed5ecbc82b4654973438d119daba0c4cf0724 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/408895 Tested-by: SPDK Automated Test System Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/nvme/nvme_ctrlr.c | 23 +++++++------------ lib/nvme/nvme_internal.h | 5 +++- lib/nvme/nvme_ns.c | 2 +- lib/nvme/nvme_pcie.c | 10 +++++++- lib/nvme/nvme_rdma.c | 9 +++++++- test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c | 9 +++++++- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 4d8adfa8a..c90b01216 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -62,7 +62,7 @@ nvme_ctrlr_get_cap(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cap_register * &cap->raw); } -static int +int nvme_ctrlr_get_vs(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_vs_register *vs) { return nvme_transport_ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, vs.raw), @@ -819,8 +819,7 @@ nvme_ctrlr_identify_active_ns(struct spdk_nvme_ctrlr *ctrlr) return -ENOMEM; } status.done = false; - if (SPDK_NVME_VERSION(ctrlr->cdata.ver.bits.mjr, ctrlr->cdata.ver.bits.mnr, - ctrlr->cdata.ver.bits.ter) >= SPDK_NVME_VERSION(1, 1, 0)) { + if (ctrlr->vs.raw >= SPDK_NVME_VERSION(1, 1, 0)) { /* * Iterate through the pages and fetch each chunk of 1024 namespaces until * there are no more active namespaces @@ -1197,13 +1196,10 @@ nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr, static int _nvme_ctrlr_configure_aer(struct spdk_nvme_ctrlr *ctrlr) { - const struct spdk_nvme_ctrlr_data *cdata; union spdk_nvme_feat_async_event_configuration config; struct nvme_completion_poll_status status; int rc; - cdata = spdk_nvme_ctrlr_get_data(ctrlr); - config.raw = 0; config.bits.crit_warn.bits.available_spare = 1; config.bits.crit_warn.bits.temperature = 1; @@ -1211,7 +1207,7 @@ _nvme_ctrlr_configure_aer(struct spdk_nvme_ctrlr *ctrlr) config.bits.crit_warn.bits.read_only = 1; config.bits.crit_warn.bits.volatile_memory_backup = 1; - if (cdata->ver.raw >= SPDK_NVME_VERSION(1, 2, 0)) { + if (ctrlr->vs.raw >= SPDK_NVME_VERSION(1, 2, 0)) { if (ctrlr->cdata.oaes.ns_attribute_notices) { config.bits.ns_attr_notice = 1; } @@ -1219,7 +1215,7 @@ _nvme_ctrlr_configure_aer(struct spdk_nvme_ctrlr *ctrlr) config.bits.fw_activation_notice = 1; } } - if (cdata->ver.raw >= SPDK_NVME_VERSION(1, 3, 0) && cdata->lpa.telemetry) { + if (ctrlr->vs.raw >= SPDK_NVME_VERSION(1, 3, 0) && ctrlr->cdata.lpa.telemetry) { config.bits.telemetry_log_notice = 1; } @@ -1759,9 +1755,11 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr) /* This function should be called once at ctrlr initialization to set up constant properties. */ void -nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap) +nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap, + const union spdk_nvme_vs_register *vs) { ctrlr->cap = *cap; + ctrlr->vs = *vs; ctrlr->min_page_size = 1u << (12 + ctrlr->cap.bits.mpsmin); @@ -1885,12 +1883,7 @@ union spdk_nvme_cap_register spdk_nvme_ctrlr_get_regs_cap(struct spdk_nvme_ctrlr union spdk_nvme_vs_register spdk_nvme_ctrlr_get_regs_vs(struct spdk_nvme_ctrlr *ctrlr) { - union spdk_nvme_vs_register vs; - - if (nvme_ctrlr_get_vs(ctrlr, &vs)) { - vs.raw = 0xFFFFFFFFu; - } - return vs; + return ctrlr->vs; } uint32_t diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 56c0f0d5d..86c8b5caa 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -405,6 +405,7 @@ struct spdk_nvme_ctrlr { /* Cold data (not accessed in normal I/O path) is after this point. */ union spdk_nvme_cap_register cap; + union spdk_nvme_vs_register vs; enum nvme_ctrlr_state state; uint64_t state_timeout_tsc; @@ -588,7 +589,9 @@ void nvme_ctrlr_connected(struct spdk_nvme_ctrlr *ctrlr); int nvme_ctrlr_submit_admin_request(struct spdk_nvme_ctrlr *ctrlr, struct nvme_request *req); int nvme_ctrlr_get_cap(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cap_register *cap); -void nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap); +int nvme_ctrlr_get_vs(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_vs_register *vs); +void nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap, + const union spdk_nvme_vs_register *vs); int nvme_qpair_init(struct spdk_nvme_qpair *qpair, uint16_t id, struct spdk_nvme_ctrlr *ctrlr, enum spdk_nvme_qprio qprio, diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 05e3f4da8..e85ff857a 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -124,7 +124,7 @@ int nvme_ns_identify_update(struct spdk_nvme_ns *ns) } memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list)); - if (ns->ctrlr->cdata.ver.raw >= SPDK_NVME_VERSION(1, 3, 0)) { + if (ns->ctrlr->vs.raw >= SPDK_NVME_VERSION(1, 3, 0)) { SPDK_DEBUGLOG(SPDK_LOG_NVME, "Attempting to retrieve NS ID Descriptor List\n"); status.done = false; rc = nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST, 0, ns->id, diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index 860bbe163..c41dea453 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -774,6 +774,7 @@ struct spdk_nvme_ctrlr *nvme_pcie_ctrlr_construct(const struct spdk_nvme_transpo struct spdk_pci_device *pci_dev = devhandle; struct nvme_pcie_ctrlr *pctrlr; union spdk_nvme_cap_register cap; + union spdk_nvme_vs_register vs; uint32_t cmd_reg; int rc, claim_fd; struct spdk_pci_id pci_id; @@ -824,7 +825,14 @@ struct spdk_nvme_ctrlr *nvme_pcie_ctrlr_construct(const struct spdk_nvme_transpo return NULL; } - nvme_ctrlr_init_cap(&pctrlr->ctrlr, &cap); + if (nvme_ctrlr_get_vs(&pctrlr->ctrlr, &vs)) { + SPDK_ERRLOG("get_vs() failed\n"); + close(claim_fd); + spdk_dma_free(pctrlr); + return NULL; + } + + nvme_ctrlr_init_cap(&pctrlr->ctrlr, &cap, &vs); /* Doorbell stride is 2 ^ (dstrd + 2), * but we want multiples of 4, so drop the + 2 */ diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index 9678305de..3ec29b67e 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -1369,6 +1369,7 @@ struct spdk_nvme_ctrlr *nvme_rdma_ctrlr_construct(const struct spdk_nvme_transpo { struct nvme_rdma_ctrlr *rctrlr; union spdk_nvme_cap_register cap; + union spdk_nvme_vs_register vs; int rc; rctrlr = calloc(1, sizeof(struct nvme_rdma_ctrlr)); @@ -1400,7 +1401,13 @@ struct spdk_nvme_ctrlr *nvme_rdma_ctrlr_construct(const struct spdk_nvme_transpo return NULL; } - nvme_ctrlr_init_cap(&rctrlr->ctrlr, &cap); + if (nvme_ctrlr_get_vs(&rctrlr->ctrlr, &vs)) { + SPDK_ERRLOG("get_vs() failed\n"); + nvme_ctrlr_destruct(&rctrlr->ctrlr); + return NULL; + } + + nvme_ctrlr_init_cap(&rctrlr->ctrlr, &cap, &vs); SPDK_DEBUGLOG(SPDK_LOG_NVME, "succesully initialized the nvmf ctrlr\n"); return &rctrlr->ctrlr; diff --git a/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c b/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c index d905506f3..36abba061 100644 --- a/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c +++ b/test/unit/lib/nvme/nvme_pcie.c/nvme_pcie_ut.c @@ -204,8 +204,15 @@ nvme_ctrlr_get_cap(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cap_register * abort(); } +int +nvme_ctrlr_get_vs(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_vs_register *vs) +{ + abort(); +} + void -nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap) +nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cap_register *cap, + const union spdk_nvme_vs_register *vs) { abort(); }