[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 01/10] Rework transmitter packet code to use an internal cache of objects
Use XENVIF_TRANSMITTER_PACKET_V2 for queueing packets, with a translation on entry and exit through the interface (for v1) Renames XENVIF_TRANSMITTER_PACKET to XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET_V2 is allocated from a cache and not included inline in the miniport reserved area of a NET_BUFFER, like XENVIF_TRANSMITTER_PACKET_V1. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- include/vif_interface.h | 37 ++-- src/xenvif/transmitter.c | 477 ++++++++++++++++++++++++++++++++--------------- src/xenvif/transmitter.h | 6 +- src/xenvif/vif.c | 12 +- src/xenvif/vif.h | 4 +- 5 files changed, 368 insertions(+), 168 deletions(-) diff --git a/include/vif_interface.h b/include/vif_interface.h index 498ed8f..8bde731 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -257,7 +257,7 @@ struct _XENVIF_TRANSMITTER_PACKET_V1 { }; }; -typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET, *PXENVIF_TRANSMITTER_PACKET; +typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET_V1, *PXENVIF_TRANSMITTER_PACKET_V1; #pragma warning(pop) @@ -265,9 +265,24 @@ typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET, *PXENVIF C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof (PVOID))); +/*! \struct _XENVIF_TRANSMITTER_PACKER_V2 + \brief Transmit-side packet structure +*/ +struct _XENVIF_TRANSMITTER_PACKET_V2 { + LIST_ENTRY ListEntry; + PMDL Mdl; + ULONG Offset; + ULONG Length; + PVOID Cookie; + XENVIF_TRANSMITTER_PACKET_SEND_INFO Send; + XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion; +}; + +typedef struct _XENVIF_TRANSMITTER_PACKET_V2 XENVIF_TRANSMITTER_PACKET_V2, *PXENVIF_TRANSMITTER_PACKET_V2; + /*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET \brief Offsets of packet metadata relative to - XENVIF_TRANSMITTER_PACKET pointer + XENVIF_TRANSMITTER_PACKET_V1 pointer Because the transmit side packet structure is limited to 3 pointer types in size, not all information about the packet can be passed in @@ -380,10 +395,10 @@ typedef VOID \param ... Additional paramaters required by \a Type \b XENVIF_TRANSMITTER_RETURN_PACKETS: - \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET + \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET_V1 \b XENVIF_RECEIVER_QUEUE_PACKETS: - \param List List of XENVIF_TRANSMITTER_PACKET + \param List List of XENVIF_RECEIVER_PACKET \b XENVIF_MAC_STATE_CHANGE: No additional arguments @@ -459,7 +474,7 @@ typedef VOID /*! \typedef XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET \brief Set byte offset of packet information relative to - XENVIF_TRANSMITTER_PACKET pointer. + XENVIF_TRANSMITTER_PACKET_V1 pointer. See \ref _XENVIF_TRANSMITTER_PACKET_OFFSET. @@ -474,16 +489,16 @@ typedef NTSTATUS IN LONG_PTR Value ); -/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS +/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1 \brief Queue transmit side packets at the provider \param Interface The interface header - \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET + \param Head The head of a chain of XENVIF_TRANSMITTER_PACKET_V1 */ typedef NTSTATUS -(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS)( - IN PINTERFACE Interface, - IN PXENVIF_TRANSMITTER_PACKET Head +(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1)( + IN PINTERFACE Interface, + IN PXENVIF_TRANSMITTER_PACKET_V1 Head ); /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS @@ -694,7 +709,7 @@ struct _XENVIF_VIF_INTERFACE_V1 { XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions; XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize; XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET TransmitterSetPacketOffset; - XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS TransmitterQueuePackets; + XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1 TransmitterQueuePackets; XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions; XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize; XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE TransmitterQueryRingSize; diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c index 8125a5a..38e4cb2 100644 --- a/src/xenvif/transmitter.c +++ b/src/xenvif/transmitter.c @@ -88,7 +88,7 @@ typedef struct _XENVIF_TRANSMITTER_FRAGMENT { #define XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID 0x03FF typedef struct _XENVIF_TRANSMITTER_STATE { - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; XENVIF_TRANSMITTER_PACKET_SEND_INFO Send; PUCHAR StartVa; XENVIF_PACKET_INFO Info; @@ -100,8 +100,8 @@ typedef struct _XENVIF_TRANSMITTER_STATE { #define XENVIF_TRANSMITTER_RING_SIZE (__CONST_RING_SIZE(netif_tx, PAGE_SIZE)) typedef struct _XENVIF_TRANSMITTER_PACKET_LIST { - PXENVIF_TRANSMITTER_PACKET HeadPacket; - PXENVIF_TRANSMITTER_PACKET *TailPacket; + PLIST_ENTRY HeadEntry; + PLIST_ENTRY *TailEntry; } XENVIF_TRANSMITTER_PACKET_LIST, *PXENVIF_TRANSMITTER_PACKET_LIST; typedef struct _XENVIF_TRANSMITTER_RING { @@ -118,7 +118,7 @@ typedef struct _XENVIF_TRANSMITTER_RING { BOOLEAN Connected; BOOLEAN Enabled; BOOLEAN Stopped; - PXENVIF_TRANSMITTER_PACKET Lock; + PLIST_ENTRY Lock; PKTHREAD LockThread; XENVIF_TRANSMITTER_PACKET_LIST Queued; XENVIF_TRANSMITTER_STATE State; @@ -133,7 +133,7 @@ typedef struct _XENVIF_TRANSMITTER_RING { ULONG RequestsPushed; ULONG ResponsesProcessed; ULONG PacketsSent; - XENVIF_TRANSMITTER_PACKET_LIST Completed; + LIST_ENTRY Completed; ULONG PacketsCompleted; PSOCKADDR_INET AddressTable; ULONG AddressCount; @@ -146,6 +146,7 @@ struct _XENVIF_TRANSMITTER { PXENVIF_FRONTEND Frontend; XENBUS_CACHE_INTERFACE CacheInterface; XENBUS_RANGE_SET_INTERFACE RangeSetInterface; + PXENBUS_CACHE PacketCache; LIST_ENTRY List; LONG_PTR Offset[XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT]; ULONG DisableIpVersion4Gso; @@ -362,7 +363,7 @@ __TransmitterGetFragment( TRUE); } -static FORCEINLINE +static FORCEINLINE VOID __TransmitterPutFragment( IN PXENVIF_TRANSMITTER_RING Ring, IN PXENVIF_TRANSMITTER_FRAGMENT Fragment @@ -387,6 +388,67 @@ __TransmitterPutFragment( TRUE); } +static NTSTATUS +TransmitterPacketCtor( + IN PVOID Argument, + IN PVOID Object + ) +{ + UNREFERENCED_PARAMETER(Argument); + RtlZeroMemory(Object, sizeof(XENVIF_TRANSMITTER_PACKET_V2)); + return STATUS_SUCCESS; +} + +static VOID +TransmitterPacketDtor( + IN PVOID Argument, + IN PVOID Object + ) +{ + UNREFERENCED_PARAMETER(Argument); + UNREFERENCED_PARAMETER(Object); +} + +static VOID +TransmitterPacketLock( + IN PVOID Argument + ) +{ + UNREFERENCED_PARAMETER(Argument); +} + +static VOID +TransmitterPacketUnlock( + IN PVOID Argument + ) +{ + UNREFERENCED_PARAMETER(Argument); +} + +static FORCEINLINE PXENVIF_TRANSMITTER_PACKET_V2 +__TransmitterGetPacket( + IN PXENVIF_TRANSMITTER Transmitter + ) +{ + return XENBUS_CACHE(Get, + &Transmitter->CacheInterface, + Transmitter->PacketCache, + TRUE); +} + +static FORCEINLINE VOID +__TransmitterPutPacket( + IN PXENVIF_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET_V2 Packet + ) +{ + XENBUS_CACHE(Put, + &Transmitter->CacheInterface, + Transmitter->PacketCache, + Packet, + TRUE); +} + static VOID TransmitterRingDebugCallback( IN PVOID Argument, @@ -523,25 +585,25 @@ fail1: return FALSE; } -#define INCREMENT_PACKET_REFERENCE(_Packet) \ - do { \ - PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->Next; \ - \ - ASSERT(Packet != NULL); \ - (*Reference)++; \ +#define INCREMENT_PACKET_REFERENCE(_Packet) \ + do { \ + PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->ListEntry.Flink; \ + \ + ASSERT(Packet != NULL); \ + (*Reference)++; \ } while (FALSE) -#define DECREMENT_PACKET_REFERENCE(_Packet) \ - do { \ - PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->Next; \ - \ - ASSERT(Packet != NULL); \ - ASSERT(*Reference != 0); \ - --(*Reference); \ +#define DECREMENT_PACKET_REFERENCE(_Packet) \ + do { \ + PULONG_PTR Reference = (PULONG_PTR)&(_Packet)->ListEntry.Flink; \ + \ + ASSERT(Packet != NULL); \ + ASSERT(*Reference != 0); \ + --(*Reference); \ } while (FALSE) -#define PACKET_REFERENCE(_Packet) \ - (*(PULONG_PTR)&(_Packet)->Next) +#define PACKET_REFERENCE(_Packet) \ + (*(PULONG_PTR)&(_Packet)->ListEntry.Flink) static FORCEINLINE NTSTATUS __TransmitterRingCopyPayload( @@ -551,7 +613,7 @@ __TransmitterRingCopyPayload( PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; PXENVIF_TRANSMITTER_STATE State; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; XENVIF_PACKET_PAYLOAD Payload; PXENVIF_TRANSMITTER_FRAGMENT Fragment; PXENVIF_TRANSMITTER_BUFFER Buffer; @@ -698,7 +760,7 @@ __TransmitterRingGrantPayload( PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; PXENVIF_TRANSMITTER_STATE State; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; PXENVIF_PACKET_PAYLOAD Payload; PMDL Mdl; ULONG Offset; @@ -845,7 +907,7 @@ __TransmitterRingPrepareHeader( PXENVIF_FRONTEND Frontend; PXENVIF_MAC Mac; PXENVIF_TRANSMITTER_STATE State; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; PXENVIF_PACKET_PAYLOAD Payload; PXENVIF_PACKET_INFO Info; PXENVIF_TRANSMITTER_FRAGMENT Fragment; @@ -1122,7 +1184,7 @@ __TransmitterRingUnprepareFragments( while (State->Count != 0) { PLIST_ENTRY ListEntry; PXENVIF_TRANSMITTER_FRAGMENT Fragment; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; --State->Count; @@ -1178,19 +1240,10 @@ __TransmitterRingUnprepareFragments( static FORCEINLINE NTSTATUS __TransmitterRingPreparePacket( - IN PXENVIF_TRANSMITTER_RING Ring, - IN PXENVIF_TRANSMITTER_PACKET Packet + IN PXENVIF_TRANSMITTER_RING Ring, + IN PXENVIF_TRANSMITTER_PACKET_V2 Packet ) { -#define OFFSET_EXISTS(_Ring, _Packet, _Type) \ - ((_Ring)->Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET] != 0) - -#define OFFSET(_Ring, _Packet, _Type) \ - ((OFFSET_EXISTS(_Ring, _Packet, _Type)) ? \ - (PVOID)((PUCHAR)(_Packet) + \ - (_Ring)->Transmitter->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET]) : \ - NULL) - PXENVIF_TRANSMITTER Transmitter; PXENVIF_TRANSMITTER_STATE State; PXENVIF_PACKET_PAYLOAD Payload; @@ -1198,7 +1251,7 @@ __TransmitterRingPreparePacket( NTSTATUS status; ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE))); - ASSERT3P(Packet->Next, ==, NULL); + ASSERT3P(Packet->ListEntry.Flink, ==, NULL); Transmitter = Ring->Transmitter; @@ -1211,16 +1264,9 @@ __TransmitterRingPreparePacket( Payload = &State->Payload; - ASSERT(OFFSET_EXISTS(Ring, Packet, MDL)); - Payload->Mdl = *(PMDL *)OFFSET(Ring, Packet, MDL); - - if (OFFSET_EXISTS(Ring, Packet, OFFSET)) - Payload->Offset = *(PULONG)OFFSET(Ring, Packet, OFFSET); - else - Payload->Offset = 0; - - ASSERT(OFFSET_EXISTS(Ring, Packet, LENGTH)); - Payload->Length = *(PULONG)OFFSET(Ring, Packet, LENGTH); + Payload->Mdl = Packet->Mdl; + Payload->Offset = Packet->Offset; + Payload->Length = Packet->Length; InitializeListHead(&State->List); ASSERT3U(State->Count, ==, 0); @@ -1325,18 +1371,15 @@ fail1: ASSERT(IsZeroMemory(&Ring->State, sizeof (XENVIF_TRANSMITTER_STATE))); return status; - -#undef OFFSET -#undef OFFSET_EXISTS } -static FORCEINLINE PXENVIF_TRANSMITTER_PACKET +static FORCEINLINE PXENVIF_TRANSMITTER_PACKET_V2 __TransmitterRingUnpreparePacket( IN PXENVIF_TRANSMITTER_RING Ring ) { PXENVIF_TRANSMITTER_STATE State; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; State = &Ring->State; Packet = State->Packet; @@ -1695,7 +1738,7 @@ __TransmitterRingPostFragments( PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; PXENVIF_TRANSMITTER_STATE State; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; PXENVIF_PACKET_PAYLOAD Payload; RING_IDX req_prod; RING_IDX rsp_cons; @@ -1920,8 +1963,8 @@ __TransmitterRingFakeResponses( static FORCEINLINE VOID __TransmitterRingCompletePacket( - IN PXENVIF_TRANSMITTER_RING Ring, - IN PXENVIF_TRANSMITTER_PACKET Packet + IN PXENVIF_TRANSMITTER_RING Ring, + IN PXENVIF_TRANSMITTER_PACKET_V2 Packet ) { PXENVIF_TRANSMITTER Transmitter; @@ -1980,9 +2023,9 @@ __TransmitterRingCompletePacket( } } - *Ring->Completed.TailPacket = Packet; - ASSERT3P(Packet->Next, ==, NULL); - Ring->Completed.TailPacket = &Packet->Next; + ASSERT3P(Packet->ListEntry.Flink, ==, NULL); + ASSERT3P(Packet->ListEntry.Blink, ==, NULL); + InsertTailList(&Ring->Completed, &Packet->ListEntry); Ring->PacketsCompleted++; } @@ -2019,7 +2062,7 @@ TransmitterRingPoll( netif_tx_response_t *rsp; uint16_t id; PXENVIF_TRANSMITTER_FRAGMENT Fragment; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; rsp = RING_GET_RESPONSE(&Ring->Front, rsp_cons); rsp_cons++; @@ -2164,30 +2207,30 @@ __TransmitterRingPushRequests( static FORCEINLINE ULONG __TransmitterReversePacketList( - IN PXENVIF_TRANSMITTER_PACKET *Packet + IN PLIST_ENTRY *Entry ) { - PXENVIF_TRANSMITTER_PACKET HeadPacket; + PLIST_ENTRY HeadEntry; ULONG Count; - HeadPacket = NULL; + HeadEntry = NULL; Count = 0; - while (*Packet != NULL) { - PXENVIF_TRANSMITTER_PACKET Next; + while (*Entry != NULL) { + PLIST_ENTRY Next; - ASSERT(((ULONG_PTR)*Packet & XENVIF_TRANSMITTER_LOCK_BIT) == 0); + ASSERT(((ULONG_PTR)*Entry & XENVIF_TRANSMITTER_LOCK_BIT) == 0); - Next = (*Packet)->Next; + Next = (*Entry)->Flink; - (*Packet)->Next = HeadPacket; - HeadPacket = *Packet; + (*Entry)->Flink = HeadEntry; + HeadEntry = *Entry; - *Packet = Next; + *Entry = Next; Count++; } - *Packet = HeadPacket; + *Entry = HeadEntry; return Count; } @@ -2199,8 +2242,8 @@ TransmitterRingSwizzle( { ULONG_PTR Old; ULONG_PTR New; - PXENVIF_TRANSMITTER_PACKET HeadPacket; - PXENVIF_TRANSMITTER_PACKET *TailPacket; + PLIST_ENTRY HeadEntry; + PLIST_ENTRY *TailEntry; ULONG Count; ASSERT3P(Ring->LockThread, ==, KeGetCurrentThread()); @@ -2209,21 +2252,21 @@ TransmitterRingSwizzle( Old = (ULONG_PTR)InterlockedExchangePointer(&Ring->Lock, (PVOID)New); ASSERT(Old & XENVIF_TRANSMITTER_LOCK_BIT); - HeadPacket = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT); + HeadEntry = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT); - if (HeadPacket == NULL) + if (HeadEntry == NULL) return; // Packets are held in the atomic packet list in reverse order // so that the most recent is always head of the list. This is // necessary to allow addition to the list to be done atomically. - TailPacket = &HeadPacket->Next; - Count = __TransmitterReversePacketList(&HeadPacket); - ASSERT3P(*TailPacket, ==, NULL); + TailEntry = &HeadEntry->Flink; + Count = __TransmitterReversePacketList(&HeadEntry); + ASSERT3P(*TailEntry, ==, NULL); - *(Ring->Queued.TailPacket) = HeadPacket; - Ring->Queued.TailPacket = TailPacket; + *(Ring->Queued.TailEntry) = HeadEntry; + Ring->Queued.TailEntry = TailEntry; Ring->PacketsQueued += Count; } @@ -2240,8 +2283,9 @@ TransmitterRingSchedule( State = &Ring->State; for (;;) { - PXENVIF_TRANSMITTER_PACKET Packet; - NTSTATUS status; + PLIST_ENTRY ListEntry; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; + NTSTATUS status; if (State->Count != 0) { status = __TransmitterRingPostFragments(Ring); @@ -2290,19 +2334,20 @@ TransmitterRingSchedule( continue; } - Packet = Ring->Queued.HeadPacket; - - if (Packet == NULL) + ListEntry = Ring->Queued.HeadEntry; + if (ListEntry == NULL) break; - if (Packet->Next == NULL) { - Ring->Queued.HeadPacket = NULL; - Ring->Queued.TailPacket = &Ring->Queued.HeadPacket; + if (ListEntry->Flink == NULL) { + Ring->Queued.HeadEntry = NULL; + Ring->Queued.TailEntry = &Ring->Queued.HeadEntry; } else { - Ring->Queued.HeadPacket = Packet->Next; - Packet->Next = NULL; + Ring->Queued.HeadEntry = ListEntry->Flink; + ListEntry->Flink = NULL; } + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2, ListEntry); + status = __TransmitterRingPreparePacket(Ring, Packet); if (!NT_SUCCESS(status)) { PXENVIF_TRANSMITTER Transmitter; @@ -2330,11 +2375,46 @@ TransmitterRingSchedule( ASSERT3U(Ring->PacketsPrepared, ==, Ring->PacketsCopied + Ring->PacketsGranted + Ring->PacketsFaked); } - ASSERT(IMPLY(Ring->Queued.HeadPacket == NULL, Ring->Queued.TailPacket == &Ring->Queued.HeadPacket)); + ASSERT(IMPLY(Ring->Queued.HeadEntry == NULL, Ring->Queued.TailEntry == &Ring->Queued.HeadEntry)); __TransmitterRingPushRequests(Ring); } +static VOID +TransmitterReturnPackets( + IN PXENVIF_TRANSMITTER Transmitter, + IN PLIST_ENTRY List + ) +{ + PXENVIF_FRONTEND Frontend; + PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket; + PXENVIF_TRANSMITTER_PACKET_V1 NextPacket; + + HeadPacket = NULL; + NextPacket = NULL; + while (!IsListEmpty(List)) { + PLIST_ENTRY ListEntry; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; + + ListEntry = RemoveTailList(List); + ASSERT3P(ListEntry, !=, List); + + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2, ListEntry); + + HeadPacket = Packet->Cookie; + HeadPacket->Next = NextPacket; + HeadPacket->Completion = Packet->Completion; + + __TransmitterPutPacket(Transmitter, Packet); + NextPacket = HeadPacket; + } + + Frontend = Transmitter->Frontend; + + VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)), + HeadPacket); +} + static FORCEINLINE BOOLEAN __drv_requiresIRQL(DISPATCH_LEVEL) __TransmitterRingTryAcquireLock( @@ -2427,16 +2507,29 @@ __TransmitterRingTryReleaseLock( } static FORCEINLINE VOID +__AppendTailList( + IN OUT PLIST_ENTRY List, + IN OUT PLIST_ENTRY Apendee + ) +{ + PLIST_ENTRY HeadEntry = Apendee->Flink; + + if (!IsListEmpty(Apendee)) { + RemoveEntryList(Apendee); + InitializeListHead(Apendee); + AppendTailList(List, HeadEntry); + } +} + +static FORCEINLINE VOID __drv_requiresIRQL(DISPATCH_LEVEL) __TransmitterRingReleaseLock( IN PXENVIF_TRANSMITTER_RING Ring ) { - PXENVIF_TRANSMITTER_PACKET HeadPacket; - PXENVIF_TRANSMITTER_PACKET *TailPacket; - - HeadPacket = NULL; - TailPacket = &HeadPacket; + LIST_ENTRY List; + + InitializeListHead(&List); ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); @@ -2449,22 +2542,11 @@ __TransmitterRingReleaseLock( TransmitterRingSwizzle(Ring); TransmitterRingSchedule(Ring); - *TailPacket = Ring->Completed.HeadPacket; - TailPacket = Ring->Completed.TailPacket; - - Ring->Completed.HeadPacket = NULL; - Ring->Completed.TailPacket = &Ring->Completed.HeadPacket; + __AppendTailList(&List, &Ring->Completed); } while (!__TransmitterRingTryReleaseLock(Ring)); - if (HeadPacket != NULL) { - PXENVIF_TRANSMITTER Transmitter; - PXENVIF_FRONTEND Frontend; - - Transmitter = Ring->Transmitter; - Frontend = Transmitter->Frontend; - - VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)), - HeadPacket); + if (!IsListEmpty(&List)) { + TransmitterReturnPackets(Ring->Transmitter, &List); } } @@ -2624,8 +2706,8 @@ __TransmitterRingInitialize( (*Ring)->Transmitter = Transmitter; (*Ring)->Index = Index; - (*Ring)->Queued.TailPacket = &(*Ring)->Queued.HeadPacket; - (*Ring)->Completed.TailPacket = &(*Ring)->Completed.HeadPacket; + (*Ring)->Queued.TailEntry = &(*Ring)->Queued.HeadEntry; + InitializeListHead(&(*Ring)->Completed); status = RtlStringCbPrintfA(Name, sizeof (Name), @@ -2756,8 +2838,8 @@ fail3: fail2: Error("fail2\n"); - (*Ring)->Queued.TailPacket = NULL; - (*Ring)->Completed.TailPacket = NULL; + (*Ring)->Queued.TailEntry = NULL; + RtlZeroMemory(&(*Ring)->Completed, sizeof(LIST_ENTRY)); (*Ring)->Index = 0; (*Ring)->Transmitter = NULL; @@ -2910,7 +2992,7 @@ __TransmitterRingDisable( { PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; - PXENVIF_TRANSMITTER_PACKET Packet; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; PCHAR Buffer; XenbusState State; ULONG Attempt; @@ -2929,14 +3011,15 @@ __TransmitterRingDisable( // Put any packet back on the head of the queue if (Packet != NULL) { - ASSERT3P(Packet->Next, ==, NULL); + ASSERT3P(Packet->ListEntry.Flink, ==, NULL); + ASSERT3P(Packet->ListEntry.Blink, ==, NULL); - Packet->Next = Ring->Queued.HeadPacket; + Packet->ListEntry.Flink = Ring->Queued.HeadEntry; - if (Ring->Queued.TailPacket == &Ring->Queued.HeadPacket) - Ring->Queued.TailPacket = &Packet->Next; + if (Ring->Queued.TailEntry == &Ring->Queued.HeadEntry) + Ring->Queued.TailEntry = &Packet->ListEntry.Flink; - Ring->Queued.HeadPacket = Packet; + Ring->Queued.HeadEntry = &Packet->ListEntry; } Ring->AddressIndex = 0; @@ -3076,11 +3159,11 @@ __TransmitterRingTeardown( Ring->BufferCache); Ring->BufferCache = NULL; - ASSERT3P(Ring->Queued.TailPacket, ==, &Ring->Queued.HeadPacket); - Ring->Queued.TailPacket = NULL; + ASSERT3P(Ring->Queued.TailEntry, ==, &Ring->Queued.HeadEntry); + Ring->Queued.TailEntry = NULL; - ASSERT3P(Ring->Completed.TailPacket, ==, &Ring->Completed.HeadPacket); - Ring->Completed.TailPacket = NULL; + ASSERT(IsListEmpty(&Ring->Completed)); + RtlZeroMemory(&Ring->Completed, sizeof(LIST_ENTRY)); Ring->Index = 0; Ring->Transmitter = NULL; @@ -3092,24 +3175,40 @@ __TransmitterRingTeardown( static FORCEINLINE VOID __TransmitterRingQueuePackets( IN PXENVIF_TRANSMITTER_RING Ring, - IN PXENVIF_TRANSMITTER_PACKET HeadPacket + IN PLIST_ENTRY List ) { - PXENVIF_TRANSMITTER_PACKET *TailPacket; + PLIST_ENTRY ListEntry; + PLIST_ENTRY HeadEntry; + PLIST_ENTRY *TailEntry; ULONG_PTR Old; ULONG_PTR LockBit; ULONG_PTR New; - TailPacket = &HeadPacket->Next; - (VOID) __TransmitterReversePacketList(&HeadPacket); - ASSERT3P(*TailPacket, ==, NULL); + ListEntry = RemoveTailList(List); + ASSERT3P(ListEntry, !=, List); + + ListEntry->Flink = NULL; + ListEntry->Blink = NULL; + HeadEntry = ListEntry; + + TailEntry = &ListEntry->Flink; + while (!IsListEmpty(List)) { + ListEntry = RemoveTailList(List); + ASSERT3P(ListEntry, !=, List); + + ListEntry->Flink = HeadEntry; + ListEntry->Blink = NULL; + HeadEntry = ListEntry; + } + ASSERT3P(*TailEntry, ==, NULL); do { Old = (ULONG_PTR)Ring->Lock; LockBit = Old & XENVIF_TRANSMITTER_LOCK_BIT; - *TailPacket = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT); - New = (ULONG_PTR)HeadPacket; + *TailEntry = (PVOID)(Old & ~XENVIF_TRANSMITTER_LOCK_BIT); + New = (ULONG_PTR)HeadEntry; ASSERT((New & XENVIF_TRANSMITTER_LOCK_BIT) == 0); New |= LockBit; } while ((ULONG_PTR)InterlockedCompareExchangePointer(&Ring->Lock, (PVOID)New, (PVOID)Old) != Old); @@ -3128,33 +3227,35 @@ __TransmitterRingAbortPackets( IN PXENVIF_TRANSMITTER_RING Ring ) { - PXENVIF_TRANSMITTER_PACKET Packet; + PLIST_ENTRY ListEntry; __TransmitterRingAcquireLock(Ring); TransmitterRingSwizzle(Ring); - Packet = Ring->Queued.HeadPacket; + ListEntry = Ring->Queued.HeadEntry; - Ring->Queued.HeadPacket = NULL; - Ring->Queued.TailPacket = &Ring->Queued.HeadPacket; + Ring->Queued.HeadEntry = NULL; + Ring->Queued.TailEntry = &Ring->Queued.HeadEntry; - while (Packet != NULL) { - PXENVIF_TRANSMITTER_PACKET Next; + while (ListEntry != NULL) { + PLIST_ENTRY Next; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; - Next = Packet->Next; - Packet->Next = NULL; + Next = ListEntry->Flink; + ListEntry->Flink = NULL; // Fake that we prapared and sent this packet Ring->PacketsPrepared++; Ring->PacketsSent++; Ring->PacketsFaked++; + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2, ListEntry); Packet->Completion.Status = XENVIF_TRANSMITTER_PACKET_DROPPED; __TransmitterRingCompletePacket(Ring, Packet); - Packet = Next; + ListEntry = Next; } ASSERT3U(Ring->PacketsSent, ==, Ring->PacketsPrepared - Ring->PacketsUnprepared); @@ -3264,13 +3365,27 @@ TransmitterInitialize( if (!NT_SUCCESS(status)) goto fail3; + status = XENBUS_CACHE(Create, + &(*Transmitter)->CacheInterface, + "packet_cache", + sizeof(XENVIF_TRANSMITTER_PACKET_V2), + 0, + TransmitterPacketCtor, + TransmitterPacketDtor, + TransmitterPacketLock, + TransmitterPacketUnlock, + *Transmitter, + &(*Transmitter)->PacketCache); + if (!NT_SUCCESS(status)) + goto fail4; + Index = 0; while (Index < Count) { PXENVIF_TRANSMITTER_RING Ring; status = __TransmitterRingInitialize(*Transmitter, Index, &Ring); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; InsertTailList(&(*Transmitter)->List, &Ring->ListEntry); Index++; @@ -3278,8 +3393,8 @@ TransmitterInitialize( return STATUS_SUCCESS; -fail4: - Error("fail4\n"); +fail5: + Error("fail5\n"); while (!IsListEmpty(&(*Transmitter)->List)) { PLIST_ENTRY ListEntry; @@ -3297,6 +3412,14 @@ fail4: } ASSERT3U(Index, ==, 0); + XENBUS_CACHE(Destroy, + &(*Transmitter)->CacheInterface, + (*Transmitter)->PacketCache); + (*Transmitter)->PacketCache = NULL; + +fail4: + Error("fail4\n"); + XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface); fail3: @@ -3530,6 +3653,11 @@ TransmitterTeardown( __TransmitterRingTeardown(Ring); } + XENBUS_CACHE(Destroy, + &Transmitter->CacheInterface, + Transmitter->PacketCache); + Transmitter->PacketCache = NULL; + XENBUS_CACHE(Release, &Transmitter->CacheInterface); XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface); @@ -3620,20 +3748,77 @@ fail1: } VOID -TransmitterQueuePackets( - IN PXENVIF_TRANSMITTER Transmitter, - IN PXENVIF_TRANSMITTER_PACKET HeadPacket +TransmitterQueuePacketsV1( + IN PXENVIF_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket ) { +#define OFFSET_EXISTS(_Transmitter, _Packet, _Type) \ + ((_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET] != 0) + +#define OFFSET(_Transmitter, _Packet, _Type) \ + ((OFFSET_EXISTS(_Transmitter, _Packet, _Type)) ? \ + (PVOID)((PUCHAR)(_Packet) + \ + (_Transmitter)->Offset[XENVIF_TRANSMITTER_PACKET_ ## _Type ## _OFFSET]) : \ + NULL) + + LIST_ENTRY List; PLIST_ENTRY ListEntry; PXENVIF_TRANSMITTER_RING Ring; + InitializeListHead(&List); + while (HeadPacket != NULL) { + PXENVIF_TRANSMITTER_PACKET_V2 Packet; + + Packet = __TransmitterGetPacket(Transmitter); + if (Packet == NULL) { + Warning("Out-of-cached-packets\n"); + break; + } + + Packet->Cookie = HeadPacket; + RtlCopyMemory(&Packet->Send, &HeadPacket->Send, sizeof(Packet->Send)); + RtlZeroMemory(&Packet->Completion, sizeof(Packet->Completion)); + + ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, MDL)); + Packet->Mdl = *(PMDL *)OFFSET(Transmitter, HeadPacket, MDL); + if (OFFSET_EXISTS(Transmitter, HeadPacket, OFFSET)) + Packet->Offset = *(PULONG)OFFSET(Transmitter, HeadPacket, OFFSET); + else + Packet->Offset = 0; + ASSERT(OFFSET_EXISTS(Transmitter, HeadPacket, LENGTH)); + Packet->Length = *(PULONG)OFFSET(Transmitter, HeadPacket, LENGTH); + + InsertTailList(&List, &Packet->ListEntry); + HeadPacket = HeadPacket->Next; + } + // We need to hash for a ring eventually. Since there is only a // single ring for now, we just use that. ListEntry = Transmitter->List.Flink; Ring = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_RING, ListEntry); - __TransmitterRingQueuePackets(Ring, HeadPacket); + __TransmitterRingQueuePackets(Ring, &List); + + // if HeadPacket != NULL, errors occured and need returning + if (HeadPacket != NULL) { + PXENVIF_TRANSMITTER_PACKET_V1 Packet; + PXENVIF_FRONTEND Frontend; + + Frontend = Transmitter->Frontend; + + Packet = HeadPacket; + while (Packet != NULL) { + Packet->Completion.Status = XENVIF_TRANSMITTER_PACKET_DROPPED; + Packet = Packet->Next; + } + + VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)), + HeadPacket); + } + +#undef OFFSET +#undef OFFSET_EXISTS } VOID diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h index 5ffb590..661eeae 100644 --- a/src/xenvif/transmitter.h +++ b/src/xenvif/transmitter.h @@ -107,9 +107,9 @@ TransmitterAdvertiseAddresses( ); extern VOID -TransmitterQueuePackets( - IN PXENVIF_TRANSMITTER Transmitter, - IN PXENVIF_TRANSMITTER_PACKET HeadPacket +TransmitterQueuePacketsV1( + IN PXENVIF_TRANSMITTER Transmitter, + IN PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket ); extern VOID diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c index 97ce84a..d6da258 100644 --- a/src/xenvif/vif.c +++ b/src/xenvif/vif.c @@ -276,8 +276,8 @@ VifReceiverReturnPackets( static NTSTATUS VifTransmitterQueuePackets( - IN PINTERFACE Interface, - IN PXENVIF_TRANSMITTER_PACKET Head + IN PINTERFACE Interface, + IN PXENVIF_TRANSMITTER_PACKET_V1 Head ) { PXENVIF_VIF_CONTEXT Context = Interface->Context; @@ -289,8 +289,8 @@ VifTransmitterQueuePackets( if (Context->Enabled == FALSE) goto fail1; - TransmitterQueuePackets(FrontendGetTransmitter(Context->Frontend), - Head); + TransmitterQueuePacketsV1(FrontendGetTransmitter(Context->Frontend), + Head); ReleaseMrswLockShared(&Context->Lock); @@ -784,8 +784,8 @@ VifReceiverQueuePackets( VOID VifTransmitterReturnPackets( - IN PXENVIF_VIF_CONTEXT Context, - IN PXENVIF_TRANSMITTER_PACKET Head + IN PXENVIF_VIF_CONTEXT Context, + IN PXENVIF_TRANSMITTER_PACKET_V1 Head ) { Context->Callback(Context->Argument, diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h index 17a04db..0ef6687 100644 --- a/src/xenvif/vif.h +++ b/src/xenvif/vif.h @@ -70,8 +70,8 @@ VifReceiverQueuePackets( extern VOID VifTransmitterReturnPackets( - IN PXENVIF_VIF_CONTEXT Context, - IN PXENVIF_TRANSMITTER_PACKET Head + IN PXENVIF_VIF_CONTEXT Context, + IN PXENVIF_TRANSMITTER_PACKET_V1 Head ); extern PXENVIF_THREAD -- 1.9.4.msysgit.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |