Page MenuHomeFreeBSD

D61113.1793871489.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D61113.1793871489.diff

diff --git a/sys/dev/ufshci/ufshci_private.h b/sys/dev/ufshci/ufshci_private.h
--- a/sys/dev/ufshci/ufshci_private.h
+++ b/sys/dev/ufshci/ufshci_private.h
@@ -82,6 +82,7 @@
UFSHCI_SLOT_STATE_SCHEDULED = 0x2,
UFSHCI_SLOT_STATE_TIMEOUT = 0x3,
UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING = 0x4,
+ UFSHCI_SLOT_STATE_COMPLETING = 0x5,
};
struct ufshci_tracker {
diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -209,7 +209,7 @@
mtx_lock(&hwq->qlock);
- for (i = 0; i < req_queue->num_trackers; i++) {
+ for (i = 0; i < hwq->num_trackers; i++) {
tr = hwq->act_tr[i];
/*
@@ -222,11 +222,11 @@
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.
+ * Claim the tracker under the lock. Every other walker
+ * skips a slot in this state, so the tracker cannot
+ * complete twice while the lock is dropped.
*/
- tr->slot_state = UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING;
+ tr->slot_state = UFSHCI_SLOT_STATE_COMPLETING;
mtx_unlock(&hwq->qlock);
ufshci_req_queue_manual_complete_tracker(tr,
UFSHCI_DESC_ABORTED,
@@ -491,7 +491,12 @@
* complete the command manually.
*/
mtx_lock(&tr->hwq->qlock);
- if (tr->slot_state != UFSHCI_SLOT_STATE_FREE) {
+ /*
+ * Only a scheduled slot still waits on the controller. Claim it
+ * before the unlock, so no other path completes it as well.
+ */
+ if (tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED) {
+ tr->slot_state = UFSHCI_SLOT_STATE_COMPLETING;
mtx_unlock(&tr->hwq->qlock);
/*
* An I/O has timed out, and the controller was unable to abort
diff --git a/sys/dev/ufshci/ufshci_req_sdb.c b/sys/dev/ufshci/ufshci_req_sdb.c
--- a/sys/dev/ufshci/ufshci_req_sdb.c
+++ b/sys/dev/ufshci/ufshci_req_sdb.c
@@ -595,7 +595,7 @@
bus_dmamap_sync(hwq->dma_tag_queue, hwq->queuemem_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- for (slot = 0; slot < req_queue->num_entries; slot++) {
+ for (slot = 0; slot < hwq->num_trackers; slot++) {
bool completed;
tr = hwq->act_tr[slot];
@@ -609,6 +609,12 @@
mtx_lock(&hwq->qlock);
completed = tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED &&
req_queue->qops.is_completed(req_queue->ctrlr, slot);
+ /*
+ * Claim the slot while the lock is held, so no other path
+ * completes this request as well.
+ */
+ if (completed)
+ tr->slot_state = UFSHCI_SLOT_STATE_COMPLETING;
mtx_unlock(&hwq->qlock);
if (completed) {
ufshci_req_queue_complete_tracker(tr);

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 5, 9:38 AM (6 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41360528
Default Alt Text
D61113.1793871489.diff (2 KB)

Event Timeline