nvme: use RTD3E to determine shutdown timeout
NVMe 1.2 introduced a new Identify Controller field, RTD3E ("RTD3 Entry Latency"), which allows the device to report the expected time for a normal shutdown. Use this as the timeout for the shutdown process when available instead of hard-coding 5 seconds. Some devices may report a RTD3E time that is shorter than their actual shutdown time in practice; force the timeout to be at least 10 seconds to allow for a reasonable amount of shutdown time. This doesn't add any extra delay for devices that do complete the shutdown process within their reported RTD3E time, since we will return as soon as the device reports that it is finished shutting down. Change-Id: Ibc04b3fc08a3486cf785ae969bba9243c572cd31 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/386688 Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
6890888888
commit
4fd2131ea8
@ -481,7 +481,8 @@ nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
union spdk_nvme_cc_register cc;
|
||||
union spdk_nvme_csts_register csts;
|
||||
int ms_waited = 0;
|
||||
uint32_t ms_waited = 0;
|
||||
uint32_t shutdown_timeout_ms;
|
||||
|
||||
if (ctrlr->is_removed) {
|
||||
return;
|
||||
@ -500,11 +501,18 @@ nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)
|
||||
}
|
||||
|
||||
/*
|
||||
* The NVMe spec does not define a timeout period
|
||||
* for shutdown notification, so we just pick
|
||||
* 5 seconds as a reasonable amount of time to
|
||||
* The NVMe specification defines RTD3E to be the time between
|
||||
* setting SHN = 1 until the controller will set SHST = 10b.
|
||||
* If the device doesn't report RTD3 entry latency, or if it
|
||||
* reports RTD3 entry latency less than 10 seconds, pick
|
||||
* 10 seconds as a reasonable amount of time to
|
||||
* wait before proceeding.
|
||||
*/
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_NVME, "RTD3E = %" PRIu32 " us\n", ctrlr->cdata.rtd3e);
|
||||
shutdown_timeout_ms = (ctrlr->cdata.rtd3e + 999) / 1000;
|
||||
shutdown_timeout_ms = spdk_max(shutdown_timeout_ms, 10000);
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_NVME, "shutdown timeout = %" PRIu32 " ms\n", shutdown_timeout_ms);
|
||||
|
||||
do {
|
||||
if (nvme_ctrlr_get_csts(ctrlr, &csts)) {
|
||||
SPDK_ERRLOG("get_csts() failed\n");
|
||||
@ -512,15 +520,16 @@ nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)
|
||||
}
|
||||
|
||||
if (csts.bits.shst == SPDK_NVME_SHST_COMPLETE) {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_NVME, "shutdown complete\n");
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_NVME, "shutdown complete in %u milliseconds\n",
|
||||
ms_waited);
|
||||
return;
|
||||
}
|
||||
|
||||
nvme_delay(1000);
|
||||
ms_waited++;
|
||||
} while (ms_waited < 5000);
|
||||
} while (ms_waited < shutdown_timeout_ms);
|
||||
|
||||
SPDK_ERRLOG("did not shutdown within 5 seconds\n");
|
||||
SPDK_ERRLOG("did not shutdown within %u milliseconds\n", shutdown_timeout_ms);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user