Use RTD3 Entry Latency value as shutdown timeout.

This field was not in specs when the driver was written, but now there
are SSDs with the reported latency of 10s, where hardcoded value of 5s
seems to be not enough sometimes, causing shutdown timeout messages.

MFC after:	1 week
Sponsored by:	iXsystems, Inc.
This commit is contained in:
mav 2020-10-14 15:50:28 +00:00
parent aa6aa07859
commit 56d097d368

View File

@ -1510,22 +1510,24 @@ nvme_ctrlr_shutdown(struct nvme_controller *ctrlr)
{ {
uint32_t cc; uint32_t cc;
uint32_t csts; uint32_t csts;
int ticks = 0; int ticks = 0, timeout;
cc = nvme_mmio_read_4(ctrlr, cc); cc = nvme_mmio_read_4(ctrlr, cc);
cc &= ~(NVME_CC_REG_SHN_MASK << NVME_CC_REG_SHN_SHIFT); cc &= ~(NVME_CC_REG_SHN_MASK << NVME_CC_REG_SHN_SHIFT);
cc |= NVME_SHN_NORMAL << NVME_CC_REG_SHN_SHIFT; cc |= NVME_SHN_NORMAL << NVME_CC_REG_SHN_SHIFT;
nvme_mmio_write_4(ctrlr, cc, cc); nvme_mmio_write_4(ctrlr, cc, cc);
timeout = ctrlr->cdata.rtd3e == 0 ? 5 * hz :
((uint64_t)ctrlr->cdata.rtd3e * hz + 999999) / 1000000;
while (1) { while (1) {
csts = nvme_mmio_read_4(ctrlr, csts); csts = nvme_mmio_read_4(ctrlr, csts);
if (csts == 0xffffffff) /* Hot unplug. */ if (csts == 0xffffffff) /* Hot unplug. */
break; break;
if (NVME_CSTS_GET_SHST(csts) == NVME_SHST_COMPLETE) if (NVME_CSTS_GET_SHST(csts) == NVME_SHST_COMPLETE)
break; break;
if (ticks++ > 5*hz) { if (ticks++ > timeout) {
nvme_printf(ctrlr, "did not complete shutdown within" nvme_printf(ctrlr, "did not complete shutdown within"
" 5 seconds of notification\n"); " %d ticks of notification\n", timeout);
break; break;
} }
pause("nvme shn", 1); pause("nvme shn", 1);