Commit acb9d248 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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.

Change-Id: I14e7223c81ba397771cf00b49f034f25d21b6e82
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/385301


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 3ac878b0
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -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,19 @@ nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)
	}

	/*
	 * The NVMe spec does not define a timeout period
	 *  for shutdown notification, so we just pick
	 * 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, pick
	 *  5 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;
	if (shutdown_timeout_ms == 0) {
		shutdown_timeout_ms = 5000;
	}
	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");
@@ -518,7 +527,7 @@ nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)

		nvme_delay(1000);
		ms_waited++;
	} while (ms_waited < 5000);
	} while (ms_waited < shutdown_timeout_ms);

	SPDK_ERRLOG("did not shutdown within 5 seconds\n");
}