git: c686e7d3b0d3 - main - ufshci: check completions under the queue lock

Jaeyoon Choi <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a793803.1f0a2.1f3ff227__2761.50000733963$1786329274$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by jaeyoon:

URL: https://cgit.FreeBSD.org/src/commit/?id=c686e7d3b0d315c358be81b4a1151711213d998d

commit c686e7d3b0d315c358be81b4a1151711213d998d
Author:     Jaeyoon Choi <[email protected]>
AuthorDate: 2026-08-10 01:49:31 +0000
Commit:     Jaeyoon Choi <[email protected]>
CommitDate: 2026-08-10 02:28:53 +0000

    ufshci: check completions under the queue lock
    
    The completion scan held only the recovery lock. The submit path sets
    a slot to SCHEDULED and then rings the doorbell, both under the queue
    lock. A scan running between those two steps saw a SCHEDULED slot with
    a clear doorbell and completed a command the device had not started.
    The command failed with OCS 0xf, and a reused slot could return wrong
    read data.
    
    Check the slot state and the doorbell under the queue lock. The submit
    path holds it across both steps, so a half-submitted slot can no
    longer be seen. Found with fio randrw verify on QEMU.
    
    Sponsored by:           Samsung Electronics
    Reviewed by:            imp (mentor)
    Differential Revision:  https://reviews.freebsd.org/D58668
---
 sys/dev/ufshci/ufshci_req_sdb.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_req_sdb.c b/sys/dev/ufshci/ufshci_req_sdb.c
index 9f3a2a866ae0..80c4e53230e3 100644
--- a/sys/dev/ufshci/ufshci_req_sdb.c
+++ b/sys/dev/ufshci/ufshci_req_sdb.c
@@ -584,16 +584,23 @@ ufshci_req_sdb_process_cpl(struct ufshci_req_queue *req_queue)
 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 	for (slot = 0; slot < req_queue->num_entries; slot++) {
+		bool completed;
+
 		tr = hwq->act_tr[slot];
 
 		KASSERT(tr, ("there is no tracker assigned to the slot"));
 		/*
 		 * When the response is delivered from the device, the doorbell
-		 * is cleared.
+		 * is cleared. Check it under qlock so that a slot whose
+		 * doorbell write is still in flight in the submit path is not
+		 * mistaken for a completed one.
 		 */
-		if (tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED &&
+		mtx_lock(&hwq->qlock);
+		completed = tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED &&
 		    req_queue->qops.is_doorbell_cleared(req_queue->ctrlr,
-			slot)) {
+			slot);
+		mtx_unlock(&hwq->qlock);
+		if (completed) {
 			ufshci_req_queue_complete_tracker(tr);
 			done = true;
 		}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.