Date: Wed, 17 Mar 2021 14:35:51 GMT From: Alexander Motin <mav@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 4fbbe523653b - main - nvme: Replace potentially long DELAY() with pause(). Message-ID: <202103171435.12HEZppO025805@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=4fbbe523653b6d2a0186aca38224efcab941deaa commit 4fbbe523653b6d2a0186aca38224efcab941deaa Author: Alexander Motin <mav@FreeBSD.org> AuthorDate: 2021-03-17 14:30:40 +0000 Commit: Alexander Motin <mav@FreeBSD.org> CommitDate: 2021-03-17 14:35:49 +0000 nvme: Replace potentially long DELAY() with pause(). In some cases like broken hardware nvme(4) may wait minutes for controller response before timeout. Doing so in a tight spin loop made whole system unresponsive. Reviewed by: imp MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D29309 Sponsored by: iXsystems, Inc. --- sys/dev/nvme/nvme_ctrlr.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 9e45c0e2d19e..b6befb2c88d0 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -255,10 +255,9 @@ nvme_ctrlr_fail_req_task(void *arg, int pending) static int nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_val) { - int ms_waited; + int timeout = ticks + (uint64_t)ctrlr->ready_timeout_in_ms * hz / 1000; uint32_t csts; - ms_waited = 0; while (1) { csts = nvme_mmio_read_4(ctrlr, csts); if (csts == NVME_GONE) /* Hot unplug. */ @@ -266,12 +265,12 @@ nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_val) if (((csts >> NVME_CSTS_REG_RDY_SHIFT) & NVME_CSTS_REG_RDY_MASK) == desired_val) break; - if (ms_waited++ > ctrlr->ready_timeout_in_ms) { + if (timeout - ticks < 0) { nvme_printf(ctrlr, "controller ready did not become %d " "within %d ms\n", desired_val, ctrlr->ready_timeout_in_ms); return (ENXIO); } - DELAY(1000); + pause("nvmerdy", 1); } return (0); @@ -410,7 +409,7 @@ nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr) nvme_ctrlr_disable_qpairs(ctrlr); - DELAY(100*1000); + pause("nvmehwreset", hz / 10); err = nvme_ctrlr_disable(ctrlr); if (err != 0) @@ -1536,27 +1535,26 @@ nvme_ctrlr_shutdown(struct nvme_controller *ctrlr) { uint32_t cc; uint32_t csts; - int ticks = 0, timeout; + int timeout; cc = nvme_mmio_read_4(ctrlr, cc); cc &= ~(NVME_CC_REG_SHN_MASK << NVME_CC_REG_SHN_SHIFT); cc |= NVME_SHN_NORMAL << NVME_CC_REG_SHN_SHIFT; nvme_mmio_write_4(ctrlr, cc, cc); - timeout = ctrlr->cdata.rtd3e == 0 ? 5 * hz : - ((uint64_t)ctrlr->cdata.rtd3e * hz + 999999) / 1000000; + timeout = ticks + (ctrlr->cdata.rtd3e == 0 ? 5 * hz : + ((uint64_t)ctrlr->cdata.rtd3e * hz + 999999) / 1000000); while (1) { csts = nvme_mmio_read_4(ctrlr, csts); if (csts == NVME_GONE) /* Hot unplug. */ break; if (NVME_CSTS_GET_SHST(csts) == NVME_SHST_COMPLETE) break; - if (ticks++ > timeout) { - nvme_printf(ctrlr, "did not complete shutdown within" - " %d ticks of notification\n", timeout); + if (timeout - ticks < 0) { + nvme_printf(ctrlr, "shutdown timeout\n"); break; } - pause("nvme shn", 1); + pause("nvmeshut", 1); } } @@ -1633,7 +1631,7 @@ nvme_ctrlr_suspend(struct nvme_controller *ctrlr) */ nvme_ctrlr_delete_qpairs(ctrlr); nvme_ctrlr_disable_qpairs(ctrlr); - DELAY(100*1000); + pause("nvmesusp", hz / 10); nvme_ctrlr_shutdown(ctrlr); return (0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103171435.12HEZppO025805>