[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 |