From 2226750a7ceda50801f10a0fa60f47d5ed482911 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Thu, 1 Aug 2019 21:42:54 -0400 Subject: [PATCH] nvme: add an option 'no_shn_notification' to driver spdk_nvme_detach() will do the normal shutdown notification for most cases, and it will take some time e.g. 2 seconds to finish the process for PCIe based controllers. If users' environment has several drives, each drive will call spdk_nvme_detach() one by one, and the shutdown process may take very long time. Since users know exactly what they would like to do for the next step, so here we provide an option to users, users can enable it to skip the shutdown notification process so that they can have very quick shutdown process, and when starting next time, the controller can be enabled again. Change-Id: Ie7f87115d57776729fab4cdac489cae6dc13511b Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/463949 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Paul Luse Reviewed-by: Ben Walker --- CHANGELOG.md | 7 +++++++ include/spdk/nvme.h | 5 +++++ lib/nvme/nvme_ctrlr.c | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2b5a4dc..73a330543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## v19.10: (Upcoming Release) +### nvme + +Added `no_shn_notification` to NVMe controller initialization options, users can enable +it for NVMe controllers. When the option is enabled, the controller will not do the +shutdown process and just disable the controller, users can start their application +later again to initialize the controller to the ready state. + ### iSCSI Portals may no longer be associated with a cpumask. The scheduling of diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index b8fc4ed85..add66a8cd 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -71,6 +71,11 @@ struct spdk_nvme_ctrlr_opts { */ bool use_cmb_sqs; + /** + * Don't initiate shutdown processing + */ + bool no_shn_notification; + /** * Type of arbitration mechanism */ diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 9694eb248..b343831c7 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -111,6 +111,10 @@ spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts->use_cmb_sqs = true; } + if (FIELD_OK(no_shn_notification)) { + opts->no_shn_notification = false; + } + if (FIELD_OK(arb_mechanism)) { opts->arb_mechanism = SPDK_NVME_CC_AMS_RR; } @@ -686,6 +690,30 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr) return 0; } +static int +nvme_ctrlr_disable(struct spdk_nvme_ctrlr *ctrlr) +{ + union spdk_nvme_cc_register cc; + + if (nvme_ctrlr_get_cc(ctrlr, &cc)) { + SPDK_ERRLOG("get_cc() failed\n"); + return -EIO; + } + + if (cc.bits.en == 0) { + return 0; + } + + cc.bits.en = 0; + + if (nvme_ctrlr_set_cc(ctrlr, &cc)) { + SPDK_ERRLOG("set_cc() failed\n"); + return -EIO; + } + + return 0; +} + #ifdef DEBUG static const char * nvme_ctrlr_state_string(enum nvme_ctrlr_state state) @@ -2366,7 +2394,13 @@ nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr) nvme_ctrlr_free_doorbell_buffer(ctrlr); - nvme_ctrlr_shutdown(ctrlr); + if (ctrlr->opts.no_shn_notification) { + SPDK_INFOLOG(SPDK_LOG_NVME, "Disable SSD: %s without shutdown notification\n", + ctrlr->trid.traddr); + nvme_ctrlr_disable(ctrlr); + } else { + nvme_ctrlr_shutdown(ctrlr); + } nvme_ctrlr_destruct_namespaces(ctrlr);