[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Update to XENVIF_VIF interface version 8
This version of the interface provides an explicit queue index to the XENVIF_RECEIVER_QUEUE_PACKET callback. This patch also fixes a leak of NET_BUFFER_LIST structures that can occur if the low resources threshold is reached. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/vif_interface.h | 39 ++++++++++++++++++++-- src/xennet.inf | 6 ++-- src/xennet/adapter.c | 3 ++ src/xennet/receiver.c | 89 +++++++++++++++++++++++++++++++------------------ src/xennet/receiver.h | 1 + 5 files changed, 101 insertions(+), 37 deletions(-) diff --git a/include/vif_interface.h b/include/vif_interface.h index 4a95989..38872bc 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -383,6 +383,7 @@ typedef VOID \param Completion Packet completion information \b XENVIF_RECEIVER_QUEUE_PACKET: + \param Index The index of the queue on which the packet was received \param Mdl The initial MDL of the packet \param Offset The offset of the packet data in the initial MDL \param Length The total length of the packet @@ -1006,7 +1007,41 @@ struct _XENVIF_VIF_INTERFACE_V7 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; -typedef struct _XENVIF_VIF_INTERFACE_V7 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; +/*! \struct _XENVIF_VIF_INTERFACE_V8 + \brief VIF interface version 8 + \ingroup interfaces +*/ +struct _XENVIF_VIF_INTERFACE_V8 { + INTERFACE Interface; + XENVIF_VIF_ACQUIRE Acquire; + XENVIF_VIF_RELEASE Release; + XENVIF_VIF_ENABLE Enable; + XENVIF_VIF_DISABLE Disable; + XENVIF_VIF_QUERY_STATISTIC QueryStatistic; + XENVIF_VIF_QUERY_RING_COUNT QueryRingCount; + XENVIF_VIF_UPDATE_HASH_MAPPING UpdateHashMapping; + XENVIF_VIF_RECEIVER_RETURN_PACKET ReceiverReturnPacket; + XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions; + XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE ReceiverSetBackfillSize; + XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize; + XENVIF_VIF_RECEIVER_SET_HASH_ALGORITHM ReceiverSetHashAlgorithm; + XENVIF_VIF_RECEIVER_QUERY_HASH_CAPABILITIES ReceiverQueryHashCapabilities; + XENVIF_VIF_RECEIVER_UPDATE_HASH_PARAMETERS ReceiverUpdateHashParameters; + XENVIF_VIF_TRANSMITTER_QUEUE_PACKET TransmitterQueuePacket; + XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions; + XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize; + XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE TransmitterQueryRingSize; + XENVIF_VIF_MAC_QUERY_STATE MacQueryState; + XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE MacQueryMaximumFrameSize; + XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS MacQueryPermanentAddress; + XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS MacQueryCurrentAddress; + XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES MacQueryMulticastAddresses; + XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES MacSetMulticastAddresses; + XENVIF_VIF_MAC_SET_FILTER_LEVEL MacSetFilterLevel; + XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; +}; + +typedef struct _XENVIF_VIF_INTERFACE_V8 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; /*! \def XENVIF_VIF \brief Macro at assist in method invocation @@ -1017,6 +1052,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V7 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER #endif // _WINDLL #define XENVIF_VIF_INTERFACE_VERSION_MIN 2 -#define XENVIF_VIF_INTERFACE_VERSION_MAX 7 +#define XENVIF_VIF_INTERFACE_VERSION_MAX 8 #endif // _XENVIF_INTERFACE_H diff --git a/src/xennet.inf b/src/xennet.inf index d50e6b3..d38b0c2 100644 --- a/src/xennet.inf +++ b/src/xennet.inf @@ -61,9 +61,9 @@ xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll ; DisplayName Section DeviceID ; ----------- ------- -------- -%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_0800000C -%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_0800000C -%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_0800000C +%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_0800000D +%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_0800000D +%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_0800000D [XenNet_Inst] Characteristics=0x84 diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index 6587db4..9a062e1 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -220,6 +220,7 @@ AdapterVifCallback( break; } case XENVIF_RECEIVER_QUEUE_PACKET: { + ULONG Index; PMDL Mdl; ULONG Offset; ULONG Length; @@ -231,6 +232,7 @@ AdapterVifCallback( BOOLEAN More; PVOID Cookie; + Index = va_arg(Arguments, ULONG); Mdl = va_arg(Arguments, PMDL); Offset = va_arg(Arguments, ULONG); Length = va_arg(Arguments, ULONG); @@ -243,6 +245,7 @@ AdapterVifCallback( Cookie = va_arg(Arguments, PVOID); ReceiverQueuePacket(Adapter->Receiver, + Index, Mdl, Offset, Length, diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c index fc11344..a814d57 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -41,6 +41,7 @@ #include "assert.h" typedef struct _XENNET_RECEIVER_QUEUE { + KSPIN_LOCK Lock; PNET_BUFFER_LIST Head; PNET_BUFFER_LIST Tail; ULONG Count; @@ -52,7 +53,8 @@ struct _XENNET_RECEIVER { PNET_BUFFER_LIST PutList; PNET_BUFFER_LIST GetList[HVM_MAX_VCPUS]; XENNET_RECEIVER_QUEUE Queue[HVM_MAX_VCPUS]; - LONG InNDIS; + LONG Indicated; + LONG Returned; XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; }; @@ -185,24 +187,38 @@ __ReceiverReleaseNetBufferList( } static FORCEINLINE VOID -__ReceiverReturnNetBufferList( +__ReceiverReturnNetBufferLists( IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferList, IN BOOLEAN Cache ) { PXENVIF_VIF_INTERFACE VifInterface; - PVOID Cookie; + LONG Count; VifInterface = AdapterGetVifInterface(Receiver->Adapter); - Cookie = __ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); + Count = 0; - XENVIF_VIF(ReceiverReturnPacket, - VifInterface, - Cookie); + while (NetBufferList != NULL) { + PNET_BUFFER_LIST Next; + PVOID Cookie; + + Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + + Cookie = __ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache); - (VOID) InterlockedDecrement(&Receiver->InNDIS); + XENVIF_VIF(ReceiverReturnPacket, + VifInterface, + Cookie); + + Count++; + + NetBufferList = Next; + } + + (VOID) InterlockedAdd(&Receiver->Returned, Count); } static PNET_BUFFER_LIST @@ -314,25 +330,32 @@ __ReceiverPushPackets( ) { ULONG Flags; - LONG InNDIS; + LONG Indicated; + LONG Returned; PXENNET_RECEIVER_QUEUE Queue; PNET_BUFFER_LIST NetBufferList; ULONG Count; - InNDIS = InterlockedIncrement(&Receiver->InNDIS); - - Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL | - NDIS_RECEIVE_FLAGS_PERFECT_FILTERED; - - if (InNDIS > IN_NDIS_MAX) - Flags |= NDIS_RECEIVE_FLAGS_RESOURCES; - Queue = &Receiver->Queue[Index]; + KeAcquireSpinLockAtDpcLevel(&Queue->Lock); + NetBufferList = Queue->Head; Count = Queue->Count; - RtlZeroMemory(Queue, sizeof (XENNET_RECEIVER_QUEUE)); + Queue->Tail = Queue->Head = NULL; + Queue->Count = 0; + + KeReleaseSpinLockFromDpcLevel(&Queue->Lock); + + Indicated = InterlockedAdd(&Receiver->Indicated, Count); + Returned = Receiver->Returned; + + Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL | + NDIS_RECEIVE_FLAGS_PERFECT_FILTERED; + + if (Indicated - Returned > IN_NDIS_MAX) + Flags |= NDIS_RECEIVE_FLAGS_RESOURCES; NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter), NetBufferList, @@ -341,7 +364,7 @@ __ReceiverPushPackets( Flags); if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES) - (VOID) __ReceiverReturnNetBufferList(Receiver, NetBufferList, FALSE); + (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE); } NDIS_STATUS @@ -351,6 +374,7 @@ ReceiverInitialize( ) { NET_BUFFER_LIST_POOL_PARAMETERS Params; + ULONG Index; NDIS_STATUS status; *Receiver = ExAllocatePoolWithTag(NonPagedPool, @@ -380,6 +404,12 @@ ReceiverInitialize( if ((*Receiver)->NetBufferListPool == NULL) goto fail2; + for (Index = 0; Index < HVM_MAX_VCPUS; Index++) { + PXENNET_RECEIVER_QUEUE Queue = &(*Receiver)->Queue[Index]; + + KeInitializeSpinLock(&Queue->Lock); + } + return NDIS_STATUS_SUCCESS; fail2: @@ -397,6 +427,8 @@ ReceiverTeardown( ASSERT(Receiver != NULL); + ASSERT3U(Receiver->Returned, ==, Receiver->Indicated); + for (Index = 0; Index < HVM_MAX_VCPUS; Index++) { NetBufferList = Receiver->GetList[Index]; @@ -441,21 +473,13 @@ ReceiverReturnNetBufferLists( { UNREFERENCED_PARAMETER(ReturnFlags); - while (NetBufferList != NULL) { - PNET_BUFFER_LIST Next; - - Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - - __ReceiverReturnNetBufferList(Receiver, NetBufferList, TRUE); - - NetBufferList = Next; - } + __ReceiverReturnNetBufferLists(Receiver, NetBufferList, TRUE); } VOID ReceiverQueuePacket( IN PXENNET_RECEIVER Receiver, + IN ULONG Index, IN PMDL Mdl, IN ULONG Offset, IN ULONG Length, @@ -470,7 +494,6 @@ ReceiverQueuePacket( { PXENVIF_VIF_INTERFACE VifInterface; PNET_BUFFER_LIST NetBufferList; - ULONG Index; PXENNET_RECEIVER_QUEUE Queue; VifInterface = AdapterGetVifInterface(Receiver->Adapter); @@ -492,10 +515,10 @@ ReceiverQueuePacket( return; } - Index = KeGetCurrentProcessorNumberEx(NULL); - Queue = &Receiver->Queue[Index]; + KeAcquireSpinLockAtDpcLevel(&Queue->Lock); + if (Queue->Head == NULL) { ASSERT3U(Queue->Count, ==, 0); Queue->Head = Queue->Tail = NetBufferList; @@ -505,6 +528,8 @@ ReceiverQueuePacket( } Queue->Count++; + KeReleaseSpinLockFromDpcLevel(&Queue->Lock); + if (!More) __ReceiverPushPackets(Receiver, Index); } diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h index e753095..5b59431 100644 --- a/src/xennet/receiver.h +++ b/src/xennet/receiver.h @@ -58,6 +58,7 @@ ReceiverReturnNetBufferLists( extern VOID ReceiverQueuePacket( IN PXENNET_RECEIVER Receiver, + IN ULONG Index, IN PMDL Mdl, IN ULONG Offset, IN ULONG Length, -- 2.5.3 _______________________________________________ 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 |