]> xenbits.xensource.com Git - pvdrivers/win/xenvbd.git/commitdiff
Rework BlkifRingDisable
authorOwen Smith <owen.smith@citrix.com>
Thu, 19 Sep 2019 08:30:41 +0000 (09:30 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 19 Sep 2019 08:30:41 +0000 (09:30 +0100)
Clean up all prepared and submitted requests when the ring is disabled,
so that outstanding SRBs are returned to storport for queueing. This is
especially important on the return from suspend path, as the ring is no
longer valid, and any submitted requests would be lost and trigger a
storport target reset.
Also ignores missing requests for responses.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
src/xenvbd/ring.c

index 6edee5c24d7e9366566c3d238746b9c2e3be695e..8dcdee38cc819c2d03b65d6ef15e0957b6db8961 100644 (file)
@@ -1242,17 +1242,17 @@ BlkifRingPoll(
 
             rsp = RING_GET_RESPONSE(&BlkifRing->Front, rsp_cons);
             rsp_cons++;
-            BlkifRing->ResponsesProcessed++;
 
             BlkifRing->Stopped = FALSE;
 
             Request = __BlkifRingGetSubmittedRequest(BlkifRing,
                                                      rsp->id);
-            ASSERT3P(Request, != , NULL);
-
-            __BlkifRingCompleteResponse(BlkifRing,
-                                        Request,
-                                        rsp->status);
+            if (Request != NULL) {
+                BlkifRing->ResponsesProcessed++;
+                __BlkifRingCompleteResponse(BlkifRing,
+                                            Request,
+                                            rsp->status);
+            }
 
             if (rsp_cons - BlkifRing->Front.rsp_cons > XENVBD_BATCH(BlkifRing))
                 Retry = TRUE;
@@ -2044,57 +2044,39 @@ BlkifRingDisable(
     IN  PXENVBD_BLKIF_RING  BlkifRing
     )
 {
-    PXENVBD_RING            Ring = BlkifRing->Ring;
-    ULONG                   Attempt;
-
     Trace("====> %u\n", BlkifRing->Index);
 
     __BlkifRingAcquireLock(BlkifRing);
     ASSERT(BlkifRing->Enabled);
 
-    // Discard any pending requests
-    while (!IsListEmpty(&BlkifRing->PreparedQueue)) {
-        PLIST_ENTRY         ListEntry;
-        PXENVBD_REQUEST     Request;
-        PXENVBD_SRBEXT      SrbExt;
-        PSCSI_REQUEST_BLOCK Srb;
-
-        ListEntry = RemoveHeadList(&BlkifRing->PreparedQueue);
-        ASSERT3P(ListEntry, !=, &BlkifRing->PreparedQueue);
+    BlkifRing->Enabled = FALSE;
 
-        Request = CONTAINING_RECORD(ListEntry,
-                                    XENVBD_REQUEST,
-                                    ListEntry);
-        SrbExt = Request->SrbExt;
-        Srb = SrbExt->Srb;
-        Srb->SrbStatus = SRB_STATUS_ABORTED;
-        Srb->ScsiStatus = 0x40; // SCSI_ABORTED
+    while (!IsListEmpty(&BlkifRing->SubmittedList)) {
+        PLIST_ENTRY ListEntry;
+        PXENVBD_REQUEST Request;
 
-        BlkifRingPutRequest(BlkifRing, Request);
+        ListEntry = RemoveHeadList(&BlkifRing->SubmittedList);
+        ASSERT3P(ListEntry, !=, &BlkifRing->SubmittedList);
 
-        if (InterlockedDecrement(&SrbExt->RequestCount) == 0)
-            __BlkifRingCompleteSrb(BlkifRing, SrbExt);
+        Request = CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntry);
+        BlkifRing->ResponsesProcessed++;
+        __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
     }
 
-    Attempt = 0;
-    ASSERT3U(BlkifRing->RequestsPushed, == , BlkifRing->RequestsPosted);
-    while (BlkifRing->ResponsesProcessed != BlkifRing->RequestsPushed) {
-        Attempt++;
-        ASSERT(Attempt < 100);
-
-        // Try to move things along
-        __BlkifRingSend(BlkifRing);
-        (VOID)BlkifRingPoll(BlkifRing);
+    while (!IsListEmpty(&BlkifRing->PreparedQueue)) {
+        PLIST_ENTRY ListEntry;
+        PXENVBD_REQUEST Request;
 
-        // We are waiting for a watch event at DISPATCH_LEVEL so
-        // it is our responsibility to poll the store ring.
-        XENBUS_STORE(Poll,
-                     &Ring->StoreInterface);
+        ListEntry = RemoveHeadList(&BlkifRing->PreparedQueue);
+        ASSERT3P(ListEntry, !=, &BlkifRing->PreparedQueue);
 
-        KeStallExecutionProcessor(1000);    // 1ms
+        Request = CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntry);
+        // Dont increment ResponsesProcessed, as this is a faked response
+        __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
     }
 
-    BlkifRing->Enabled = FALSE;
+    BlkifRing->Stopped = FALSE;
+
     __BlkifRingReleaseLock(BlkifRing);
 
     Trace("<==== %u\n", BlkifRing->Index);