Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Mar 2018 23:01:18 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r330954 - head/sys/dev/nvme
Message-ID:  <201803142301.w2EN1I7B037584@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Wed Mar 14 23:01:18 2018
New Revision: 330954
URL: https://svnweb.freebsd.org/changeset/base/330954

Log:
  When tearing down a queue pair, also delete the queue entries.
  
  The NVME standard has required in section 7.2.6, since at least 1.1,
  that a clean shutdown is signalled by deleting the subission and the
  completion queues before setting the shutdown bit in CC. The 1.0
  standard, apparently, did not and many of the early Intel cards didn't
  care. Some newer cards care, at least one whose beta firmware can
  scramble the card on an unclean shutdown. Linux has done this for some
  time. To make it possible to move forward with an evaluation of this
  pre-release card with wonky firmware, delete the queues on the card
  when we delete the qpair structures.
  
  Sponsored by: Netflix

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

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c	Wed Mar 14 23:01:04 2018	(r330953)
+++ head/sys/dev/nvme/nvme_ctrlr.c	Wed Mar 14 23:01:18 2018	(r330954)
@@ -514,6 +514,34 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr
 }
 
 static int
+nvme_ctrlr_destroy_qpair(struct nvme_controller *ctrlr, struct nvme_qpair *qpair)
+{
+	struct nvme_completion_poll_status	status;
+
+	status.done = 0;
+	nvme_ctrlr_cmd_delete_io_sq(qpair->ctrlr, qpair,
+	    nvme_completion_poll_cb, &status);
+	while (!atomic_load_acq_int(&status.done))
+		pause("nvme", 1);
+	if (nvme_completion_is_error(&status.cpl)) {
+		nvme_printf(ctrlr, "nvme_create_io_sq failed!\n");
+		return (ENXIO);
+	}
+
+	status.done = 0;
+	nvme_ctrlr_cmd_delete_io_cq(ctrlr, qpair,
+	    nvme_completion_poll_cb, &status);
+	while (!atomic_load_acq_int(&status.done))
+		pause("nvme", 1);
+	if (nvme_completion_is_error(&status.cpl)) {
+		nvme_printf(ctrlr, "nvme_create_io_cq failed!\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
 nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr)
 {
 	struct nvme_namespace	*ns;
@@ -1274,6 +1302,7 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, dev
 		destroy_dev(ctrlr->cdev);
 
 	for (i = 0; i < ctrlr->num_io_queues; i++) {
+		nvme_ctrlr_destroy_qpair(ctrlr, &ctrlr->ioq[i]);
 		nvme_io_qpair_destroy(&ctrlr->ioq[i]);
 	}
 



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