[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] Clear SRB queue and Shutdown queue on reset



Fix a potential hang during TargetReset.
When the ring is disabled, any SRBs queued, but not submitted were left
in the queues. These SRBs would only be recovered when StorPort's internal
timeout triggered.
When the ring is disabled, abort any SRBs that were not sent to the backend,
so that StorPort is responsible for requeueing any when the ring is re-enabled.
SRB_STATUS_ABORTED will inform StorPort to re-issue the requests when the
target has recovered, rather than failing them.

Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/ring.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index ffbd18a..4ad707f 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -2271,6 +2271,46 @@ BlkifRingDisable(
         __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
     }
 
+    // Complete any SRBs that were queued but never made it as far as the
+    // backend. Now that the ring is disabled the schedule thread will not
+    // run again, so without this these requests would be left stuck until
+    // StorPort times them out. First drain the atomic packet list into the
+    // SRB queue so that nothing accepted from a concurrent submitter is
+    // missed, then fail everything still pending. SRB_STATUS_ABORTED lets
+    // StorPort re-issue them once the target has recovered.
+
+    BlkifRingSwizzle(BlkifRing);
+
+    while (!IsListEmpty(&BlkifRing->SrbQueue)) {
+        PLIST_ENTRY ListEntry;
+        PXENVBD_SRBEXT SrbExt;
+        PSCSI_REQUEST_BLOCK Srb;
+
+        ListEntry = RemoveHeadList(&BlkifRing->SrbQueue);
+        ASSERT3P(ListEntry, !=, &BlkifRing->SrbQueue);
+
+        RtlZeroMemory(ListEntry, sizeof(LIST_ENTRY));
+
+        SrbExt = CONTAINING_RECORD(ListEntry, XENVBD_SRBEXT, ListEntry);
+        Srb = SrbExt->Srb;
+        Srb->SrbStatus = SRB_STATUS_ABORTED;
+        __BlkifRingCompleteSrb(BlkifRing, SrbExt);
+    }
+
+    while (!IsListEmpty(&BlkifRing->ShutdownQueue)) {
+        PLIST_ENTRY ListEntry;
+        PXENVBD_SRBEXT SrbExt;
+        PSCSI_REQUEST_BLOCK Srb;
+
+        ListEntry = RemoveHeadList(&BlkifRing->ShutdownQueue);
+        ASSERT3P(ListEntry, !=, &BlkifRing->ShutdownQueue);
+
+        SrbExt = CONTAINING_RECORD(ListEntry, XENVBD_SRBEXT, ListEntry);
+        Srb = SrbExt->Srb;
+        Srb->SrbStatus = SRB_STATUS_ABORTED;
+        __BlkifRingCompleteSrb(BlkifRing, SrbExt);
+    }
+
     BlkifRing->Stopped = FALSE;
 
     __BlkifRingReleaseLock(BlkifRing);
-- 
2.51.2.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.