summaryrefslogtreecommitdiffstats
path: root/sys/dev/nvme/nvme_qpair.c
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 18:45:16 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 18:45:16 +0000
commit5220c76da822d03f6c1e6e5848d8d6227d6f0ba3 (patch)
tree3df9f4b11d944ca9fffed237af1791ef45ea28db /sys/dev/nvme/nvme_qpair.c
parenta3af497c87192d7864d33b58a637530aaac4d1dc (diff)
downloadFreeBSD-src-5220c76da822d03f6c1e6e5848d8d6227d6f0ba3.zip
FreeBSD-src-5220c76da822d03f6c1e6e5848d8d6227d6f0ba3.tar.gz
Keep a doubly-linked list of outstanding trackers.
This enables in-order re-submission of I/O after a controller reset. Sponsored by: Intel
Diffstat (limited to 'sys/dev/nvme/nvme_qpair.c')
-rw-r--r--sys/dev/nvme/nvme_qpair.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index 365ae68..25b1a89 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -156,7 +156,8 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
nvme_free_request(req);
tr->req = NULL;
- SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist);
+ TAILQ_REMOVE(&qpair->outstanding_tr, tr, tailq);
+ TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq);
if (!STAILQ_EMPTY(&qpair->queued_req)) {
req = STAILQ_FIRST(&qpair->queued_req);
@@ -293,7 +294,8 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
qpair->sq_tdbl_off = nvme_mmio_offsetof(doorbell[id].sq_tdbl);
qpair->cq_hdbl_off = nvme_mmio_offsetof(doorbell[id].cq_hdbl);
- SLIST_INIT(&qpair->free_tr);
+ TAILQ_INIT(&qpair->free_tr);
+ TAILQ_INIT(&qpair->outstanding_tr);
STAILQ_INIT(&qpair->queued_req);
for (i = 0; i < qpair->num_trackers; i++) {
@@ -305,7 +307,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
}
nvme_qpair_construct_tracker(qpair, tr, i);
- SLIST_INSERT_HEAD(&qpair->free_tr, tr, slist);
+ TAILQ_INSERT_HEAD(&qpair->free_tr, tr, tailq);
}
qpair->act_tr = malloc(sizeof(struct nvme_tracker *) * qpair->num_entries,
@@ -330,9 +332,9 @@ nvme_qpair_destroy(struct nvme_qpair *qpair)
if (qpair->act_tr)
free(qpair->act_tr, M_NVME);
- while (!SLIST_EMPTY(&qpair->free_tr)) {
- tr = SLIST_FIRST(&qpair->free_tr);
- SLIST_REMOVE_HEAD(&qpair->free_tr, slist);
+ while (!TAILQ_EMPTY(&qpair->free_tr)) {
+ tr = TAILQ_FIRST(&qpair->free_tr);
+ TAILQ_REMOVE(&qpair->free_tr, tr, tailq);
bus_dmamap_destroy(qpair->dma_tag, tr->payload_dma_map);
bus_dmamap_destroy(qpair->dma_tag, tr->prp_dma_map);
free(tr, M_NVME);
@@ -513,7 +515,7 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
mtx_assert(&qpair->lock, MA_OWNED);
- tr = SLIST_FIRST(&qpair->free_tr);
+ tr = TAILQ_FIRST(&qpair->free_tr);
if (tr == NULL) {
/*
@@ -525,7 +527,8 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
return;
}
- SLIST_REMOVE_HEAD(&qpair->free_tr, slist);
+ TAILQ_REMOVE(&qpair->free_tr, tr, tailq);
+ TAILQ_INSERT_TAIL(&qpair->outstanding_tr, tr, tailq);
tr->req = req;
if (req->uio == NULL) {
OpenPOWER on IntegriCloud