diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2b5a4dce..73a330543e 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 b8fc4ed852..add66a8cd7 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 9694eb2485..b343831c72 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);