Author: mav
Date: Thu Jul  2 01:02:40 2020
New Revision: 362881
URL: https://svnweb.freebsd.org/changeset/base/362881

Log:
  MFC r362630: Fix few panics on NVMe's timing out initialization requests.

Modified:
  stable/12/sys/dev/nvme/nvme_ctrlr.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- stable/12/sys/dev/nvme/nvme_ctrlr.c Wed Jul  1 23:47:51 2020        
(r362880)
+++ stable/12/sys/dev/nvme/nvme_ctrlr.c Thu Jul  2 01:02:40 2020        
(r362881)
@@ -1020,11 +1020,20 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
        if (resetting)
                nvme_qpair_reset(&ctrlr->adminq);
 
-       for (i = 0; i < ctrlr->num_io_queues; i++)
-               nvme_qpair_reset(&ctrlr->ioq[i]);
+       if (ctrlr->ioq != NULL) {
+               for (i = 0; i < ctrlr->num_io_queues; i++)
+                       nvme_qpair_reset(&ctrlr->ioq[i]);
+       }
 
        nvme_admin_qpair_enable(&ctrlr->adminq);
 
+       /*
+        * If it was a reset on initialization command timeout, just
+        * return here, letting initialization code fail gracefully.
+        */
+       if (resetting && !ctrlr->is_initialized)
+               return;
+
        if (nvme_ctrlr_identify(ctrlr) != 0) {
                nvme_ctrlr_fail(ctrlr);
                return;
@@ -1079,7 +1088,6 @@ void
 nvme_ctrlr_start_config_hook(void *arg)
 {
        struct nvme_controller *ctrlr = arg;
-       int status;
 
        /*
         * Reset controller twice to ensure we do a transition from cc.en==1 to
@@ -1087,19 +1095,15 @@ nvme_ctrlr_start_config_hook(void *arg)
         * controller was left in when boot handed off to OS.  Linux doesn't do
         * this, however. If we adopt that policy, see also nvme_ctrlr_resume().
         */
-       status = nvme_ctrlr_hw_reset(ctrlr);
-       if (status != 0) {
+       if (nvme_ctrlr_hw_reset(ctrlr) != 0) {
+fail:
                nvme_ctrlr_fail(ctrlr);
                config_intrhook_disestablish(&ctrlr->config_hook);
                return;
        }
 
-       status = nvme_ctrlr_hw_reset(ctrlr);
-       if (status != 0) {
-               nvme_ctrlr_fail(ctrlr);
-               config_intrhook_disestablish(&ctrlr->config_hook);
-               return;
-       }
+       if (nvme_ctrlr_hw_reset(ctrlr) != 0)
+               goto fail;
 
        nvme_qpair_reset(&ctrlr->adminq);
        nvme_admin_qpair_enable(&ctrlr->adminq);
@@ -1108,7 +1112,7 @@ nvme_ctrlr_start_config_hook(void *arg)
            nvme_ctrlr_construct_io_qpairs(ctrlr) == 0)
                nvme_ctrlr_start(ctrlr, false);
        else
-               nvme_ctrlr_fail(ctrlr);
+               goto fail;
 
        nvme_sysctl_initialize_ctrlr(ctrlr);
        config_intrhook_disestablish(&ctrlr->config_hook);
@@ -1418,10 +1422,12 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, dev
                                nvme_ctrlr_hmb_enable(ctrlr, false, false);
                        nvme_ctrlr_delete_qpairs(ctrlr);
                }
+               nvme_ctrlr_hmb_free(ctrlr);
+       }
+       if (ctrlr->ioq != NULL) {
                for (i = 0; i < ctrlr->num_io_queues; i++)
                        nvme_io_qpair_destroy(&ctrlr->ioq[i]);
                free(ctrlr->ioq, M_NVME);
-               nvme_ctrlr_hmb_free(ctrlr);
        }
        nvme_admin_qpair_destroy(&ctrlr->adminq);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to