Date: Wed, 24 Mar 2021 01:26:07 GMT From: Alexander Motin <mav@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: ed407c92e43f - stable/13 - nvme: Replace potentially long DELAY() with pause(). Message-ID: <202103240126.12O1Q7rl000739@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=ed407c92e43f88652365c84dc54098a7ed479471 commit ed407c92e43f88652365c84dc54098a7ed479471 Author: Alexander Motin <mav@FreeBSD.org> AuthorDate: 2021-03-17 14:30:40 +0000 Commit: Alexander Motin <mav@FreeBSD.org> CommitDate: 2021-03-24 01:26:00 +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. (cherry picked from commit 4fbbe523653b6d2a0186aca38224efcab941deaa) --- 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 351c6839a6f6..9f86e3a8c846 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) @@ -1538,27 +1537,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); } } @@ -1635,7 +1633,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?202103240126.12O1Q7rl000739>