summaryrefslogtreecommitdiffstats
path: root/sys/dev/nvme/nvme_qpair.c
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 20:56:58 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 20:56:58 +0000
commitd0a775e7949e871c4beabbef339069ca9560c538 (patch)
treecdbd1c17b3436c5453294d11372072b2484b0800 /sys/dev/nvme/nvme_qpair.c
parentb7f7338cc5bd9736b236409a3bda233d5d88d2b3 (diff)
downloadFreeBSD-src-d0a775e7949e871c4beabbef339069ca9560c538.zip
FreeBSD-src-d0a775e7949e871c4beabbef339069ca9560c538.tar.gz
Make nvme_ctrlr_reset a nop if a reset is already in progress.
This protects against cases where a controller crashes with multiple I/O outstanding, each timing out and requesting controller resets simultaneously. While here, remove a debugging printf from a previous commit, and add more logging around I/O that need to be resubmitted after a controller reset. Sponsored by: Intel Reviewed by: carl
Diffstat (limited to 'sys/dev/nvme/nvme_qpair.c')
-rw-r--r--sys/dev/nvme/nvme_qpair.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index 602171f..b6a2633 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -142,7 +142,13 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
TAILQ_REMOVE(&qpair->outstanding_tr, tr, tailq);
TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq);
- if (!STAILQ_EMPTY(&qpair->queued_req)) {
+ /*
+ * If the controller is in the middle of resetting, don't
+ * try to submit queued requests here - let the reset logic
+ * handle that instead.
+ */
+ if (!STAILQ_EMPTY(&qpair->queued_req) &&
+ !qpair->ctrlr->is_resetting) {
req = STAILQ_FIRST(&qpair->queued_req);
STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq);
_nvme_qpair_submit_request(qpair, req);
@@ -462,8 +468,6 @@ nvme_timeout(void *arg)
/* Read csts to get value of cfs - controller fatal status. */
csts.raw = nvme_mmio_read_4(ctrlr, csts);
- device_printf(ctrlr->dev, "i/o timeout, csts.cfs=%d\n", csts.bits.cfs);
- nvme_dump_command(&tr->req->cmd);
if (ctrlr->enable_aborts && csts.bits.cfs == 0) {
/*
@@ -606,8 +610,12 @@ nvme_io_qpair_enable(struct nvme_qpair *qpair)
nvme_qpair_enable(qpair);
- TAILQ_FOREACH(tr, &qpair->outstanding_tr, tailq)
+ TAILQ_FOREACH(tr, &qpair->outstanding_tr, tailq) {
+ device_printf(qpair->ctrlr->dev,
+ "resubmitting outstanding i/o\n");
+ nvme_dump_command(&tr->req->cmd);
nvme_qpair_submit_tracker(qpair, tr);
+ }
STAILQ_INIT(&temp);
STAILQ_SWAP(&qpair->queued_req, &temp, nvme_request);
@@ -615,6 +623,9 @@ nvme_io_qpair_enable(struct nvme_qpair *qpair)
while (!STAILQ_EMPTY(&temp)) {
req = STAILQ_FIRST(&temp);
STAILQ_REMOVE_HEAD(&temp, stailq);
+ device_printf(qpair->ctrlr->dev,
+ "resubmitting queued i/o\n");
+ nvme_dump_command(&req->cmd);
_nvme_qpair_submit_request(qpair, req);
}
OpenPOWER on IntegriCloud