Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Jun 2020 20:29:29 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r362630 - head/sys/dev/nvme
Message-ID:  <202006252029.05PKTTqN009245@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Jun 25 20:29:29 2020
New Revision: 362630
URL: https://svnweb.freebsd.org/changeset/base/362630

Log:
  Fix few panics on NVMe's timing out initialization requests.
  
  MFC after:	1 week
  Sponsored by:	iXsystems, Inc.

Modified:
  head/sys/dev/nvme/nvme_ctrlr.c

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c	Thu Jun 25 20:25:35 2020	(r362629)
+++ head/sys/dev/nvme/nvme_ctrlr.c	Thu Jun 25 20:29:29 2020	(r362630)
@@ -1056,11 +1056,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;
@@ -1115,7 +1124,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
@@ -1123,19 +1131,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);
@@ -1144,7 +1148,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);
@@ -1454,10 +1458,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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202006252029.05PKTTqN009245>