git: 5f3a2b364ea5 - main - ufshci: abort submission when payload DMA mapping fails
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Aug 2026 02:31:16 UTC
The branch main has been updated by jaeyoon:
URL: https://cgit.FreeBSD.org/src/commit/?id=5f3a2b364ea51ea05daa4399693bda2021e39434
commit 5f3a2b364ea51ea05daa4399693bda2021e39434
Author: Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-08-10 01:31:43 +0000
Commit: Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-08-10 02:28:46 +0000
ufshci: abort submission when payload DMA mapping fails
When bus_dmamap_load_mem() failed, ufshci_req_queue_prepare_prdt()
manually completed and released the tracker, but its caller kept going:
it built the UTRD, set the slot back to SCHEDULED, and rang the
doorbell for a tracker whose request had already been freed. Return the
mapping error and stop the submission so the released tracker is not
resurrected.
Sponsored by: Samsung Electronics
Reviewed by: imp (mentor)
Differential Revision: https://reviews.freebsd.org/D58653
---
sys/dev/ufshci/ufshci_req_queue.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
index 4c82b79d0e26..395801274f0e 100644
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -371,7 +371,7 @@ ufshci_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
}
-static void
+static int
ufshci_req_queue_prepare_prdt(struct ufshci_tracker *tr)
{
struct ufshci_request *req = tr->req;
@@ -403,6 +403,8 @@ ufshci_req_queue_prepare_prdt(struct ufshci_tracker *tr)
UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
mtx_lock(&tr->hwq->qlock);
}
+
+ return (error);
}
static void
@@ -716,9 +718,15 @@ ufshci_req_queue_submit_tracker(struct ufshci_req_queue *req_queue,
memcpy(tr->ucd, &req->request_upiu, request_len);
memset((uint8_t *)tr->ucd + response_off, 0, response_len);
- /* Prepare PRDT */
- if (req->payload_valid)
- ufshci_req_queue_prepare_prdt(tr);
+ /*
+ * Prepare PRDT. If the payload could not be mapped, the
+ * tracker has already been completed and released by the
+ * manual completion path, so the descriptor must not be
+ * built and the doorbell must not be rung.
+ */
+ if (req->payload_valid &&
+ ufshci_req_queue_prepare_prdt(tr) != 0)
+ return;
/* Prepare UTP Transfer Request Descriptor. */
ucd_paddr = tr->ucd_bus_addr;