The branch stable/13 has been updated by mav:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ed407c92e43f88652365c84dc54098a7ed479471

commit ed407c92e43f88652365c84dc54098a7ed479471
Author:     Alexander Motin <m...@freebsd.org>
AuthorDate: 2021-03-17 14:30:40 +0000
Commit:     Alexander Motin <m...@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);
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to