git: 7682b8f37669 - main - ufshci: claim trackers before failing them
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 27 Aug 2026 05:12:46 UTC
The branch main has been updated by jaeyoon:
URL: https://cgit.FreeBSD.org/src/commit/?id=7682b8f37669671844fedd94a382ec0c459b9b2c
commit 7682b8f37669671844fedd94a382ec0c459b9b2c
Author: Jaeyoon Choi <jaeyoon@FreeBSD.org>
AuthorDate: 2026-08-27 05:00:41 +0000
Commit: Jaeyoon Choi <jaeyoon@FreeBSD.org>
CommitDate: 2026-08-27 05:08:37 +0000
ufshci: claim trackers before failing them
ufshci_req_queue_fail() drops the queue lock to complete each
tracker. In that window the completion path could complete the
same tracker again.
Claim the slot before dropping the lock, so the completion scan
skips it. Reserved slots are left to their submit thread, which
completes them itself. The manual request completion helper
lost its only caller, so drop it.
Reviewed by: imp (mentor)
Sponsored by: Samsung Electronics
Differential Revision: https://reviews.freebsd.org/D58945
---
sys/dev/ufshci/ufshci_req_queue.c | 60 +++++++++++++--------------------------
1 file changed, 20 insertions(+), 40 deletions(-)
diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
index db96d13fad24..97eccd082176 100644
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -182,29 +182,6 @@ ufshci_req_queue_manual_complete_tracker(struct ufshci_tracker *tr, uint8_t ocs,
ufshci_req_queue_complete_tracker(tr);
}
-static void
-ufshci_req_queue_manual_complete_request(struct ufshci_req_queue *req_queue,
- struct ufshci_request *req, uint8_t ocs, uint8_t rc)
-{
- struct ufshci_completion cpl;
- bool error;
-
- memset(&cpl, 0, sizeof(cpl));
- cpl.response_upiu.header.response = rc;
- error = ufshci_req_queue_response_is_error(req_queue, ocs,
- &cpl.response_upiu);
-
- if (error) {
- ufshci_printf(req_queue->ctrlr,
- "Manual complete request error:0x%x", error);
- }
-
- if (req->cb_fn)
- req->cb_fn(req->cb_arg, &cpl, error);
-
- ufshci_free_request(req);
-}
-
void
ufshci_req_queue_fail(struct ufshci_controller *ctrlr,
struct ufshci_req_queue *req_queue)
@@ -221,23 +198,26 @@ ufshci_req_queue_fail(struct ufshci_controller *ctrlr,
for (i = 0; i < req_queue->num_trackers; i++) {
tr = hwq->act_tr[i];
- if (tr->slot_state == UFSHCI_SLOT_STATE_RESERVED) {
- mtx_unlock(&hwq->qlock);
- ufshci_req_queue_manual_complete_request(req_queue,
- tr->req, UFSHCI_DESC_ABORTED,
- UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
- mtx_lock(&hwq->qlock);
- } else if (tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED) {
- /*
- * Do not remove the tracker. The abort_tracker path
- * will do that for us.
- */
- mtx_unlock(&hwq->qlock);
- ufshci_req_queue_manual_complete_tracker(tr,
- UFSHCI_DESC_ABORTED,
- UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
- mtx_lock(&hwq->qlock);
- }
+ /*
+ * A slot in UFSHCI_SLOT_STATE_RESERVED is visible here
+ * only while its submit thread is failing a PRDT setup.
+ * That thread completes the request, so leave the slot
+ * alone.
+ */
+ if (tr->slot_state != UFSHCI_SLOT_STATE_SCHEDULED)
+ continue;
+
+ /*
+ * Claim the tracker under the lock. The completion
+ * scan only completes SCHEDULED slots, so it will
+ * skip this one while the lock is dropped.
+ */
+ tr->slot_state = UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING;
+ mtx_unlock(&hwq->qlock);
+ ufshci_req_queue_manual_complete_tracker(tr,
+ UFSHCI_DESC_ABORTED,
+ UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
+ mtx_lock(&hwq->qlock);
}
mtx_unlock(&hwq->qlock);