git: b90c2b13e975 - main - nvme: complete requests when payload DMA mapping fails
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Sep 2026 15:34:30 UTC
The branch main has been updated by seuros:
URL: https://cgit.FreeBSD.org/src/commit/?id=b90c2b13e975c803e426a6e6f080a6089d08e6ab
commit b90c2b13e975c803e426a6e6f080a6089d08e6ab
Author: Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-03 15:33:49 +0000
Commit: Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-03 15:33:49 +0000
nvme: complete requests when payload DMA mapping fails
bus_dmamap_load_mem() reports most mapping failures, including EFBIG,
only through its callback and then returns zero. nvme_payload_map()
logged the error without telling the submission path, so the tracker
stayed on the outstanding list with no command submitted and no
timeout armed, stalling all later I/O on the queue behind it.
Approved by: ngie (co-mentor)
MFC after: 1 week
Reviewed by: ngie, imp
Differential Revision: https://reviews.freebsd.org/D59151
---
sys/dev/nvme/nvme_qpair.c | 37 +++++++++++--------------------------
1 file changed, 11 insertions(+), 26 deletions(-)
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index 29e373e1b00c..6411a3909917 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -1053,7 +1053,6 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
mtx_assert(&qpair->lock, MA_OWNED);
req = tr->req;
- req->cmd.cid = qpair->cid_base + tr->cid;
qpair->act_tr[tr->cid] = tr;
ctrlr = qpair->ctrlr;
@@ -1089,16 +1088,16 @@ static void
nvme_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
{
struct nvme_tracker *tr = arg;
+ struct nvme_qpair *qpair = tr->qpair;
uint32_t cur_nseg;
- /*
- * If the mapping operation failed, return immediately. The caller
- * is responsible for detecting the error status and failing the
- * tracker manually.
- */
if (error != 0) {
- nvme_printf(tr->qpair->ctrlr,
- "nvme_payload_map err %d\n", error);
+ nvme_printf(qpair->ctrlr,
+ "payload DMA mapping failed with error %d\n", error);
+ mtx_unlock(&qpair->lock);
+ nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
+ NVME_SC_DATA_TRANSFER_ERROR, DO_NOT_RETRY, ERROR_PRINT_ALL);
+ mtx_lock(&qpair->lock);
return;
}
@@ -1137,7 +1136,6 @@ static void
_nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
{
struct nvme_tracker *tr;
- int err = 0;
bool is_admin = qpair == &qpair->ctrlr->adminq;
mtx_assert(&qpair->lock, MA_OWNED);
@@ -1180,6 +1178,7 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
TAILQ_INSERT_TAIL(&qpair->outstanding_tr, tr, tailq);
tr->deadline = SBT_MAX;
tr->req = req;
+ req->cmd.cid = qpair->cid_base + tr->cid;
if (!req->payload_valid) {
nvme_qpair_submit_tracker(tr->qpair, tr);
@@ -1191,23 +1190,9 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
* nvme_qpair_submit_tracker (we call it above directly
* when there's no map to load).
*/
- err = bus_dmamap_load_mem(tr->qpair->dma_tag_payload,
- tr->payload_dma_map, &req->payload, nvme_payload_map, tr, 0);
- if (err != 0) {
- /*
- * The dmamap operation failed, so we manually fail the
- * tracker here with DATA_TRANSFER_ERROR status.
- *
- * nvme_qpair_manual_complete_tracker must not be called
- * with the qpair lock held.
- */
- nvme_printf(qpair->ctrlr,
- "bus_dmamap_load_mem returned 0x%x!\n", err);
- mtx_unlock(&qpair->lock);
- nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
- NVME_SC_DATA_TRANSFER_ERROR, DO_NOT_RETRY, ERROR_PRINT_ALL);
- mtx_lock(&qpair->lock);
- }
+ (void)bus_dmamap_load_mem(tr->qpair->dma_tag_payload,
+ tr->payload_dma_map, &req->payload, nvme_payload_map, tr,
+ BUS_DMA_NOWAIT);
}
void