]> xenbits.xensource.com Git - pvdrivers/win/xenvif.git/commitdiff
Improve transmitter disable.
authorMartin Harvey <Martin.Harvey@citrix.com>
Wed, 28 Jul 2021 14:02:43 +0000 (15:02 +0100)
committerPaul Durrant <pdurrant@amazon.com>
Thu, 5 Aug 2021 18:23:16 +0000 (19:23 +0100)
In some cases, the backend may stop processing Tx ring
requests in a timely manner. If this happens at the same time as ring
disable, then the Tx code could spin forever at dispatch IRQL.

This patch introduces a hard limit on how long the code will spin,
allowing a device disable or power transition to complete, albeit
at the cost of Tx requests being dropped or the ring being in
an indeterminate state. This has normally been seen at guest shutdown
where final ring state is of little consequence.

Signed-off-by: Martin Harvey <martin.harvey@citrix.com>
src/xenvif/transmitter.c

index f6935a66e69550aad6e020036f3e9c5f0b16f466..fddeb0cc1624f18fae14619a7b479f2197244c15 100644 (file)
@@ -3988,21 +3988,25 @@ __TransmitterRingDisable(
     ASSERT3U(Ring->RequestsPushed, ==, Ring->RequestsPosted);
     while (Ring->ResponsesProcessed != Ring->RequestsPushed) {
         Attempt++;
-        ASSERT(Attempt < 100);
+
+        KeStallExecutionProcessor(1000);    // 1ms
 
         // Try to move things along
         __TransmitterRingSend(Ring);
         (VOID) TransmitterRingPoll(Ring);
 
-        if (State != XenbusStateConnected)
-            __TransmitterRingFakeResponses(Ring);
+        if ((Attempt >= 100) || (State != XenbusStateConnected))
+            break;
 
         // We are waiting for a watch event at DISPATCH_LEVEL so
         // it is our responsibility to poll the store ring.
         XENBUS_STORE(Poll,
                      &Transmitter->StoreInterface);
-
-        KeStallExecutionProcessor(1000);    // 1ms
+    }
+    if (Ring->ResponsesProcessed != Ring->RequestsPushed)
+    {
+        __TransmitterRingFakeResponses(Ring);
+        (VOID) TransmitterRingPoll(Ring);
     }
 
     Ring->Enabled = FALSE;