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

[win-pv-devel] [PATCH] Fix an error path in transmitter hit when grant table is exhausted



If the grant table becomes exhausted then it becomes impossible to
prepare a packet for sending. Unfortunately there was a bug in the error
path in this case which causes an ASSERTion to be hit in a checked build.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/transmitter.c | 95 +++++++++++++++++++++++-------------------------
 1 file changed, 46 insertions(+), 49 deletions(-)

diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index 88add2f..415d75c 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -1427,7 +1427,7 @@ fail1:
     return status;
 }
 
-static FORCEINLINE PXENVIF_TRANSMITTER_PACKET
+static FORCEINLINE VOID
 __TransmitterRingUnprepareFragments(
     IN  PXENVIF_TRANSMITTER_RING    Ring
     )
@@ -1526,24 +1526,7 @@ __TransmitterRingUnprepareFragments(
         __TransmitterPutFragment(Ring, Fragment);
     }
 
-    if (State->Count != 0) {
-        ASSERT(IsListEmpty(&State->List));
-        RtlZeroMemory(&State->List, sizeof (LIST_ENTRY));
-
-        State->Count = 0;
-    }
-
-    Packet = State->Packet;
-
-    if (Packet != NULL) {
-        Ring->PacketsUnprepared++;
-
-        State->Packet = NULL;
-    }
-
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
-    return Packet;
+    ASSERT(IsListEmpty(&State->List));
 }
 
 static FORCEINLINE NTSTATUS
@@ -1558,15 +1541,13 @@ __TransmitterRingPreparePacket(
     PXENVIF_PACKET_INFO             Info;
     NTSTATUS                        status;
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     Transmitter = Ring->Transmitter;
 
     State = &Ring->State;
 
     State->Packet = Packet;
 
-    InitializeListHead(&State->List);
+    ASSERT(IsListEmpty(&State->List));
     ASSERT3U(State->Count, ==, 0);
 
     status = __TransmitterRingPrepareHeader(Ring);
@@ -1655,12 +1636,10 @@ fail1:
     Error("fail1 (%08x)\n", status);
 
     ASSERT(IsListEmpty(&State->List));
-    RtlZeroMemory(&State->List, sizeof (LIST_ENTRY));
+    ASSERT3U(State->Count, ==, 0);
 
     State->Packet = NULL;
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     return status;
 }
 
@@ -1687,8 +1666,6 @@ __TransmitterRingPrepareArp(
     PFN_NUMBER                      Pfn;
     NTSTATUS                        status;
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     Transmitter = Ring->Transmitter;
     Frontend = Transmitter->Frontend;
     Mac = FrontendGetMac(Frontend);
@@ -1700,6 +1677,9 @@ __TransmitterRingPrepareArp(
 
     State = &Ring->State;
 
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
+
     Buffer = __TransmitterGetBuffer(Ring);
 
     status = STATUS_NO_MEMORY;
@@ -1769,8 +1749,6 @@ __TransmitterRingPrepareArp(
     Fragment->Offset = 0;
     Fragment->Length = Mdl->ByteCount;
 
-    InitializeListHead(&State->List);
-
     ASSERT(IsZeroMemory(&Fragment->ListEntry, sizeof (LIST_ENTRY)));
     InsertTailList(&State->List, &Fragment->ListEntry);
     State->Count++;
@@ -1800,7 +1778,8 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
 
     return status;
 }
@@ -1829,8 +1808,6 @@ __TransmitterRingPrepareNeighbourAdvertisement(
     PFN_NUMBER                      Pfn;
     NTSTATUS                        status;
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     Transmitter = Ring->Transmitter;
     Frontend = Transmitter->Frontend;
     Mac = FrontendGetMac(Frontend);
@@ -1840,6 +1817,9 @@ __TransmitterRingPrepareNeighbourAdvertisement(
 
     State = &Ring->State;
 
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
+
     Buffer = __TransmitterGetBuffer(Ring);
 
     status = STATUS_NO_MEMORY;
@@ -1936,8 +1916,6 @@ __TransmitterRingPrepareNeighbourAdvertisement(
     Fragment->Offset = 0;
     Fragment->Length = Mdl->ByteCount;
 
-    InitializeListHead(&State->List);
-
     ASSERT(IsZeroMemory(&Fragment->ListEntry, sizeof (LIST_ENTRY)));
     InsertTailList(&State->List, &Fragment->ListEntry);
     State->Count++;
@@ -1967,7 +1945,8 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
 
     return status;
 }
@@ -1984,10 +1963,11 @@ __TransmitterRingPrepareMulticastControl(
     PXENVIF_TRANSMITTER_MULTICAST_CONTROL   Control;
     NTSTATUS                                status;
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     State = &Ring->State;
 
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
+
     Control = __TransmitterGetMulticastControl(Ring);
 
     status = STATUS_NO_MEMORY;
@@ -2009,8 +1989,6 @@ __TransmitterRingPrepareMulticastControl(
     Fragment->Type = XENVIF_TRANSMITTER_FRAGMENT_TYPE_MULTICAST_CONTROL;
     Control->Reference++;
 
-    InitializeListHead(&State->List);
-
     ASSERT(IsZeroMemory(&Fragment->ListEntry, sizeof (LIST_ENTRY)));
     InsertTailList(&State->List, &Fragment->ListEntry);
     State->Count++;
@@ -2025,7 +2003,8 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
 
     return status;
 }
@@ -2262,8 +2241,8 @@ __TransmitterRingPostFragments(
 
     Ring->Front.req_prod_pvt = req_prod;
 
+    ASSERT(IsListEmpty(&State->List));
     ASSERT3U(State->Count, ==, 0);
-    RtlZeroMemory(&State->List, sizeof (LIST_ENTRY));
 
     // Set the initial completion information
     if (Packet != NULL) {
@@ -2290,8 +2269,6 @@ __TransmitterRingPostFragments(
         Ring->PacketsSent++;
     }
 
-    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
-
     return STATUS_SUCCESS;
 
 fail1:
@@ -3731,12 +3708,17 @@ __TransmitterRingEnable(
 {
     PXENVIF_TRANSMITTER             Transmitter;
     PXENVIF_FRONTEND                Frontend;
+    PXENVIF_TRANSMITTER_STATE       State;
 
     Transmitter = Ring->Transmitter;
     Frontend = Transmitter->Frontend;
 
     __TransmitterRingAcquireLock(Ring);
 
+    State = &Ring->State;
+
+    InitializeListHead(&State->List);
+
     ASSERT(!Ring->Enabled);
     Ring->Enabled = TRUE;
 
@@ -3754,9 +3736,10 @@ __TransmitterRingDisable(
 {    
     PXENVIF_TRANSMITTER             Transmitter;
     PXENVIF_FRONTEND                Frontend;
+    PXENVIF_TRANSMITTER_STATE       State;
     PXENVIF_TRANSMITTER_PACKET      Packet;
     PCHAR                           Buffer;
-    XenbusState                     State;
+    XenbusState                     BackendState;
     ULONG                           Attempt;
     NTSTATUS                        status;
 
@@ -3767,12 +3750,26 @@ __TransmitterRingDisable(
 
     ASSERT(Ring->Enabled);
 
+    State = &Ring->State;
+
     // Release any fragments associated with a pending packet
-    Packet = __TransmitterRingUnprepareFragments(Ring);
+    __TransmitterRingUnprepareFragments(Ring);
+
+    ASSERT(IsListEmpty(&State->List));
+    ASSERT3U(State->Count, ==, 0);
+
+    RtlZeroMemory(&State->List, sizeof (LIST_ENTRY));
+
+    Packet = State->Packet;
+    State->Packet = NULL;
+
+    ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE)));
 
     // Put any packet back on the head of the queue
-    if (Packet != NULL)
+    if (Packet != NULL) {
+        Ring->PacketsUnprepared++;
         InsertHeadList(&Ring->PacketQueue, &Packet->ListEntry);
+    }
 
     // Discard any pending requests
     while (!IsListEmpty(&Ring->RequestQueue)) {
@@ -3797,9 +3794,9 @@ __TransmitterRingDisable(
                           "state",
                           &Buffer);
     if (!NT_SUCCESS(status)) {
-        State = XenbusStateUnknown;
+        BackendState = XenbusStateUnknown;
     } else {
-        State = (XenbusState)strtol(Buffer, NULL, 10);
+        BackendState = (XenbusState)strtol(Buffer, NULL, 10);
 
         XENBUS_STORE(Free,
                      &Transmitter->StoreInterface,
@@ -3816,7 +3813,7 @@ __TransmitterRingDisable(
         __TransmitterRingSend(Ring);
         (VOID) TransmitterRingPoll(Ring);
 
-        if (State != XenbusStateConnected)
+        if (BackendState != XenbusStateConnected)
             __TransmitterRingFakeResponses(Ring);
 
         // We are waiting for a watch event at DISPATCH_LEVEL so
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

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