summaryrefslogtreecommitdiffstats
path: root/sys/dev/nvme/nvme_qpair.c
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 21:14:51 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 21:14:51 +0000
commit21ee92ac4f6bdb321bcb61110a71cc121390f2b9 (patch)
tree373bb8bf3ef938e872f43909aca8e28c959f1d9a /sys/dev/nvme/nvme_qpair.c
parent18a3a60fb4e69d37c0f75f7989372bf51c6cd27c (diff)
downloadFreeBSD-src-21ee92ac4f6bdb321bcb61110a71cc121390f2b9.zip
FreeBSD-src-21ee92ac4f6bdb321bcb61110a71cc121390f2b9.tar.gz
Cap the number of retry attempts to a configurable number. This ensures
that if a specific I/O repeatedly times out, we don't retry it indefinitely. The default number of retries will be 4, but is adjusted using hw.nvme.retry_count. Sponsored by: Intel Reviewed by: carl
Diffstat (limited to 'sys/dev/nvme/nvme_qpair.c')
-rw-r--r--sys/dev/nvme/nvme_qpair.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index 3841095..69842b3 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -105,7 +105,8 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
req = tr->req;
error = nvme_completion_is_error(cpl);
- retry = error && nvme_completion_is_retry(cpl);
+ retry = error && nvme_completion_is_retry(cpl) &&
+ req->retries < nvme_retry_count;
if (error && print_on_error) {
nvme_dump_completion(cpl);
@@ -122,9 +123,10 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
mtx_lock(&qpair->lock);
callout_stop(&tr->timer);
- if (retry)
+ if (retry) {
+ req->retries++;
nvme_qpair_submit_tracker(qpair, tr);
- else {
+ } else {
if (req->payload_size > 0 || req->uio != NULL)
bus_dmamap_unload(qpair->dma_tag,
tr->payload_dma_map);
@@ -568,6 +570,12 @@ nvme_qpair_enable(struct nvme_qpair *qpair)
{
qpair->is_enabled = TRUE;
+}
+
+void
+nvme_qpair_reset(struct nvme_qpair *qpair)
+{
+
qpair->sq_head = qpair->sq_tail = qpair->cq_head = 0;
/*
@@ -597,19 +605,25 @@ nvme_io_qpair_enable(struct nvme_qpair *qpair)
{
STAILQ_HEAD(, nvme_request) temp;
struct nvme_tracker *tr;
+ struct nvme_tracker *tr_temp;
struct nvme_request *req;
+ /*
+ * Manually abort each outstanding I/O. This normally results in a
+ * retry, unless the retry count on the associated request has
+ * reached its limit.
+ */
+ TAILQ_FOREACH_SAFE(tr, &qpair->outstanding_tr, tailq, tr_temp) {
+ device_printf(qpair->ctrlr->dev,
+ "aborting outstanding i/o\n");
+ nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+ NVME_SC_ABORTED_BY_REQUEST, TRUE);
+ }
+
mtx_lock(&qpair->lock);
nvme_qpair_enable(qpair);
- 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);
OpenPOWER on IntegriCloud