|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |