From 6f2265734da85b5b8bde483e3c3f0a966177d900 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 19 Aug 2020 13:51:54 +0900 Subject: [PATCH] lib/nvmf: Optionalize ANA reporting feature After supporting ANA reporting by default, Linux kernel 5.3 reported error when parsing NVMe ANA log. The newer kernel fixed the issue but we should optionalize ANA reporting feature to avoid error for Linux kernel 5.3 or before. Add a bool variable ana_reporting to struct spdk_nvmf_subsystem and disable ANA reporting and initialization of related variables if it is false. We can expose MNAN (Maximum Number of Allowed Namespaces) even if ANA reporting is disabled. But MNAN is not required if ANA reporting is disabled. So do not set MNAN if it is false too. Add a public API spdk_nvmf_subsystem_set_ana_reporting() to set ana_reporting by the nvmf_create_subssytem RPC. The next patch will add ana_reporting to nvmf_create_subsystem RPC. Signed-off-by: Shuhei Matsumoto Change-Id: Icc77773b4c9513daba2f1a9fdaf951d80574f379 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3850 Community-CI: Mellanox Build Bot Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Monica Kenguva Reviewed-by: Jim Harris --- include/spdk/nvmf.h | 14 ++++++++++++++ lib/nvmf/ctrlr.c | 36 ++++++++++++++++++++++++------------ lib/nvmf/nvmf_internal.h | 1 + lib/nvmf/spdk_nvmf.map | 1 + lib/nvmf/subsystem.c | 13 +++++++++++++ 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 8e18f9c55..27a6c3d97 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -654,6 +654,20 @@ void spdk_nvmf_subsystem_allow_any_listener( bool spdk_nvmf_subsytem_any_listener_allowed( struct spdk_nvmf_subsystem *subsystem); +/** + * Set whether a subsystem supports Asymmetric Namespace Access (ANA) + * reporting. + * + * May only be performed on subsystems in the INACTIVE state. + * + * \param subsystem Subsystem to modify. + * \param ana_reporting true to support or false not to support ANA reporting. + * + * \return 0 on success, or negated errno value on failure. + */ +int spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem, + bool ana_reporting); + /** NVMe-oF target namespace creation options */ struct spdk_nvmf_ns_opts { /** diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 4afeb32bc..b6592536e 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1903,8 +1903,12 @@ nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) nvmf_get_firmware_slot_log_page(req->data, offset, len); return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; case SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS: - nvmf_get_ana_log_page(ctrlr, req->data, offset, len); - return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + if (subsystem->ana_reporting) { + nvmf_get_ana_log_page(ctrlr, req->data, offset, len); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } else { + goto invalid_log_page; + } case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG: nvmf_get_cmds_and_effects_log_page(req->data, offset, len); return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; @@ -1965,8 +1969,10 @@ spdk_nvmf_ctrlr_identify_ns(struct spdk_nvmf_ctrlr *ctrlr, nsdata->noiob = max_num_blocks; } - /* ANA group ID matches NSID. */ - nsdata->anagrpid = ns->nsid; + if (subsystem->ana_reporting) { + /* ANA group ID matches NSID. */ + nsdata->anagrpid = ns->nsid; + } return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } @@ -2017,7 +2023,9 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c cdata->sgls = ctrlr->cdata.sgls; cdata->fuses.compare_and_write = 1; cdata->acwu = 1; - cdata->mnan = subsystem->max_nsid; + if (subsystem->ana_reporting) { + cdata->mnan = subsystem->max_nsid; + } spdk_strcpy_pad(cdata->subnqn, subsystem->subnqn, sizeof(cdata->subnqn), '\0'); SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ctrlr data: maxcmd 0x%x\n", cdata->maxcmd); @@ -2034,8 +2042,10 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c cdata->rab = 6; cdata->cmic.multi_port = 1; cdata->cmic.multi_host = 1; - /* Asymmetric Namespace Access Reporting is supported. */ - cdata->cmic.ana_reporting = 1; + if (subsystem->ana_reporting) { + /* Asymmetric Namespace Access Reporting is supported. */ + cdata->cmic.ana_reporting = 1; + } cdata->oaes.ns_attribute_notices = 1; cdata->ctratt.host_id_exhid_supported = 1; /* TODO: Concurrent execution of multiple abort commands. */ @@ -2059,11 +2069,13 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c cdata->oncs.dsm = nvmf_ctrlr_dsm_supported(ctrlr); cdata->oncs.write_zeroes = nvmf_ctrlr_write_zeroes_supported(ctrlr); cdata->oncs.reservations = 1; - cdata->anacap.ana_optimized_state = 1; - /* ANAGRPID does not change while namespace is attached to controller */ - cdata->anacap.no_change_anagrpid = 1; - cdata->anagrpmax = subsystem->max_nsid; - cdata->nanagrpid = subsystem->max_nsid; + if (subsystem->ana_reporting) { + cdata->anacap.ana_optimized_state = 1; + /* ANAGRPID does not change while namespace is attached to controller */ + cdata->anacap.no_change_anagrpid = 1; + cdata->anagrpmax = subsystem->max_nsid; + cdata->nanagrpid = subsystem->max_nsid; + } nvmf_ctrlr_populate_oacs(ctrlr, cdata); diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 07c7e5ecd..f1fc55c98 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -249,6 +249,7 @@ struct spdk_nvmf_subsystem { uint16_t next_cntlid; bool allow_any_host; bool allow_any_listener; + bool ana_reporting; struct spdk_nvmf_tgt *tgt; diff --git a/lib/nvmf/spdk_nvmf.map b/lib/nvmf/spdk_nvmf.map index 23af415cf..261c03960 100644 --- a/lib/nvmf/spdk_nvmf.map +++ b/lib/nvmf/spdk_nvmf.map @@ -79,6 +79,7 @@ spdk_nvmf_transport_poll_group_get_stat; spdk_nvmf_transport_poll_group_free_stat; spdk_nvmf_rdma_init_hooks; + spdk_nvmf_subsystem_set_ana_reporting; # public functions in nvmf_cmd.h spdk_nvmf_ctrlr_identify_ctrlr; diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index ebe8d9a8e..59f52a698 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -2513,3 +2513,16 @@ nvmf_ns_reservation_request(void *ctx) update_done: _nvmf_ns_reservation_update_done(ctrlr->subsys, (void *)req, 0); } + +int +spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem, + bool ana_reporting) +{ + if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) { + return -EAGAIN; + } + + subsystem->ana_reporting = ana_reporting; + + return 0; +}