Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177191861
D61116.1793944221.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None
D61116.1793944221.diff
View Options
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
@@ -513,6 +513,7 @@
void ufshci_utr_req_queue_disable(struct ufshci_controller *ctrlr);
int ufshci_utr_req_queue_enable(struct ufshci_controller *ctrlr);
void ufshci_req_queue_stop_watchdog(struct ufshci_req_queue *req_queue);
+void ufshci_req_queue_complete_aborted_hwq(struct ufshci_hw_queue *hwq);
void ufshci_req_queue_fail(struct ufshci_controller *ctrlr,
struct ufshci_req_queue *req_queue);
int ufshci_req_queue_submit_request(struct ufshci_req_queue *req_queue,
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
@@ -220,6 +220,35 @@
ufshci_req_queue_complete_tracker(tr);
}
+/*
+ * Complete every tracker the reset claimed. The claim keeps the
+ * completion scan away, so no tracker completes twice.
+ */
+void
+ufshci_req_queue_complete_aborted_hwq(struct ufshci_hw_queue *hwq)
+{
+ struct ufshci_tracker *tr;
+ uint32_t i;
+
+ mtx_lock(&hwq->qlock);
+
+ for (i = 0; i < hwq->num_trackers; i++) {
+ tr = hwq->act_tr[i];
+
+ if (tr->slot_state != UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING)
+ continue;
+
+ tr->slot_state = UFSHCI_SLOT_STATE_COMPLETING;
+ 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);
+}
+
void
ufshci_req_queue_fail(struct ufshci_controller *ctrlr,
struct ufshci_req_queue *req_queue)
@@ -240,9 +269,12 @@
* 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.
+ * alone. A reset that failed before it enabled the queue
+ * again leaves its claimed slots behind, and nothing
+ * else completes those.
*/
- if (tr->slot_state != UFSHCI_SLOT_STATE_SCHEDULED)
+ if (tr->slot_state != UFSHCI_SLOT_STATE_SCHEDULED &&
+ tr->slot_state != UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING)
continue;
/*
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
@@ -382,6 +382,20 @@
hwq->recovery_state = RECOVERY_WAITING;
TAILQ_FOREACH_SAFE(tr, &hwq->outstanding_tr, tailq, tr_temp) {
tr->deadline = SBT_MAX;
+
+ /*
+ * A failed controller never enables the queue again, so
+ * the failure path owns the requests.
+ */
+ if (ctrlr->is_failed)
+ continue;
+
+ /*
+ * The reset wipes the request list, so nothing completes
+ * an unclaimed slot.
+ */
+ if (tr->slot_state == UFSHCI_SLOT_STATE_SCHEDULED)
+ tr->slot_state = UFSHCI_SLOT_STATE_NEED_ERROR_HANDLING;
}
mtx_unlock(&hwq->qlock);
@@ -485,6 +499,11 @@
out:
mtx_unlock(&hwq->qlock);
mtx_unlock(&hwq->recovery_lock);
+
+ /* The queue is back, so an aborted request can retry right away. */
+ if (error == 0)
+ ufshci_req_queue_complete_aborted_hwq(hwq);
+
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 6, 5:50 AM (2 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41360525
Default Alt Text
D61116.1793944221.diff (3 KB)
Attached To
Mode
D61116: ufshci: reclaim in-flight requests across a reset in SDB mode
Attached
Detach File
Event Timeline