diff options
author | jimharris <jimharris@FreeBSD.org> | 2013-03-26 20:56:58 +0000 |
---|---|---|
committer | jimharris <jimharris@FreeBSD.org> | 2013-03-26 20:56:58 +0000 |
commit | d0a775e7949e871c4beabbef339069ca9560c538 (patch) | |
tree | cdbd1c17b3436c5453294d11372072b2484b0800 /sys/dev/nvme/nvme_qpair.c | |
parent | b7f7338cc5bd9736b236409a3bda233d5d88d2b3 (diff) | |
download | FreeBSD-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.c | 19 |
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); } |