[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 4/4] Make use of batching support
XENVIF_VIF_INTERFACE version 7 adds support for batch indications on both the transmit and receive side. This patch imports the updated interface header and makes use of this new functionality. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/vif_interface.h | 56 +++++++++++++++++++-- src/xennet.inf | 6 +-- src/xennet/adapter.c | 3 ++ src/xennet/receiver.c | 126 +++++++++++++++++++++++++++++++++++------------ src/xennet/receiver.h | 1 + src/xennet/transmitter.c | 69 +++++++++++++------------- 6 files changed, 189 insertions(+), 72 deletions(-) diff --git a/include/vif_interface.h b/include/vif_interface.h index 853554d..4a95989 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -391,6 +391,7 @@ typedef VOID \param TagControlInformation The VLAN TCI (used only if OffloadOptions.OffloadTagManipulation is set) \param Info Header information for the packet \param Hash Hash information for the packet + \param More A flag to indicate whether more packets will be queued for the same CPU \param Cookie Cookie that should be passed to XENVIF_RECEIVER_RETURN_PACKET method \b XENVIF_MAC_STATE_CHANGE: @@ -527,6 +528,19 @@ typedef VOID IN PVOID Cookie ); +typedef NTSTATUS +(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5)( + IN PINTERFACE Interface, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + IN XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions, + IN USHORT MaximumSegmentSize, + IN USHORT TagControlInformation, + IN PXENVIF_PACKET_HASH Hash, + IN PVOID Cookie + ); + /*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKET \brief Queue a packet at the provider's transmit side @@ -538,6 +552,7 @@ typedef VOID \param MaximumSegmentSize The TCP MSS (used only if OffloadOptions.OffloadIpVersion[4|6]LargePacket is set) \param TagControlInformation The VLAN TCI (used only if OffloadOptions.OffloadTagManipulation is set) \param Hash Hash information for the packet + \param More A flag to indicate whether there will more packets queued with the same value of Hash \param Cookie A cookie specified by the caller that will be passed to the XENVIF_TRANSMITTER_RETURN_PACKET callback */ typedef NTSTATUS @@ -550,6 +565,7 @@ typedef NTSTATUS IN USHORT MaximumSegmentSize, IN USHORT TagControlInformation, IN PXENVIF_PACKET_HASH Hash, + IN BOOLEAN More, IN PVOID Cookie ); @@ -908,7 +924,7 @@ struct _XENVIF_VIF_INTERFACE_V5 { XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions; XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE ReceiverSetBackfillSize; XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize; - XENVIF_VIF_TRANSMITTER_QUEUE_PACKET TransmitterQueuePacket; + XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5 TransmitterQueuePacket; XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS TransmitterQueryOffloadOptions; XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE TransmitterQueryLargePacketSize; XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE TransmitterQueryRingSize; @@ -942,6 +958,40 @@ struct _XENVIF_VIF_INTERFACE_V6 { 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_V5 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; +}; + +/*! \struct _XENVIF_VIF_INTERFACE_V7 + \brief VIF interface version 7 + \ingroup interfaces +*/ +struct _XENVIF_VIF_INTERFACE_V7 { + 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; @@ -956,7 +1006,7 @@ struct _XENVIF_VIF_INTERFACE_V6 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; -typedef struct _XENVIF_VIF_INTERFACE_V6 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; +typedef struct _XENVIF_VIF_INTERFACE_V7 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; /*! \def XENVIF_VIF \brief Macro at assist in method invocation @@ -967,6 +1017,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V6 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER #endif // _WINDLL #define XENVIF_VIF_INTERFACE_VERSION_MIN 2 -#define XENVIF_VIF_INTERFACE_VERSION_MAX 6 +#define XENVIF_VIF_INTERFACE_VERSION_MAX 7 #endif // _XENVIF_INTERFACE_H diff --git a/src/xennet.inf b/src/xennet.inf index 2b42c04..d50e6b3 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_0800000B -%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_0800000B -%XenNetName% =XenNet_Inst, XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_0800000B +%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 [XenNet_Inst] Characteristics=0x84 diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index 3c161e2..6587db4 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -228,6 +228,7 @@ AdapterVifCallback( USHORT TagControlInformation; PXENVIF_PACKET_INFO Info; PXENVIF_PACKET_HASH Hash; + BOOLEAN More; PVOID Cookie; Mdl = va_arg(Arguments, PMDL); @@ -238,6 +239,7 @@ AdapterVifCallback( TagControlInformation = va_arg(Arguments, USHORT); Info = va_arg(Arguments, PXENVIF_PACKET_INFO); Hash = va_arg(Arguments, PXENVIF_PACKET_HASH); + More = va_arg(Arguments, BOOLEAN); Cookie = va_arg(Arguments, PVOID); ReceiverQueuePacket(Adapter->Receiver, @@ -249,6 +251,7 @@ AdapterVifCallback( TagControlInformation, Info, Hash, + More, Cookie); break; } diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c index 693d1ac..b76dd9a 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -40,11 +40,18 @@ #include "dbg_print.h" #include "assert.h" +typedef struct _XENNET_RECEIVER_QUEUE { + PNET_BUFFER_LIST Head; + PNET_BUFFER_LIST Tail; + ULONG Count; +} XENNET_RECEIVER_QUEUE, *PXENNET_RECEIVER_QUEUE; + struct _XENNET_RECEIVER { PXENNET_ADAPTER Adapter; NDIS_HANDLE NetBufferListPool; PNET_BUFFER_LIST PutList; PNET_BUFFER_LIST GetList[HVM_MAX_VCPUS]; + XENNET_RECEIVER_QUEUE Queue[HVM_MAX_VCPUS]; LONG InNDIS; XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; }; @@ -58,6 +65,52 @@ typedef struct _NET_BUFFER_LIST_RESERVED { C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST, MiniportReserved)); +static FORCEINLINE PNET_BUFFER_LIST +__ReceiverGetNetBufferList( + IN PXENNET_RECEIVER Receiver + ) +{ + ULONG Index; + PNET_BUFFER_LIST NetBufferList; + + Index = KeGetCurrentProcessorNumberEx(NULL); + + NetBufferList = Receiver->GetList[Index]; + + if (NetBufferList == NULL) + Receiver->GetList[Index] = + InterlockedExchangePointer(&Receiver->PutList, NULL); + + NetBufferList = Receiver->GetList[Index]; + + if (NetBufferList == NULL) + return NULL; + + Receiver->GetList[Index] = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + + return NetBufferList; +} + +static FORCEINLINE VOID +__ReceiverPutNetBufferList( + IN PXENNET_RECEIVER Receiver, + IN PNET_BUFFER_LIST NetBufferList + ) +{ + PNET_BUFFER_LIST Old; + PNET_BUFFER_LIST New; + + ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); + + do { + Old = Receiver->PutList; + + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = Old; + New = NetBufferList; + } while (InterlockedCompareExchangePointer(&Receiver->PutList, New, Old) != Old); +} + static PNET_BUFFER_LIST __ReceiverAllocateNetBufferList( IN PXENNET_RECEIVER Receiver, @@ -67,24 +120,15 @@ __ReceiverAllocateNetBufferList( IN PVOID Cookie ) { - ULONG Index; PNET_BUFFER_LIST NetBufferList; PNET_BUFFER_LIST_RESERVED ListReserved; ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); - Index = KeGetCurrentProcessorNumberEx(NULL); - - if (Receiver->GetList[Index] == NULL) - Receiver->GetList[Index] = InterlockedExchangePointer(&Receiver->PutList, NULL); - - NetBufferList = Receiver->GetList[Index]; + NetBufferList = __ReceiverGetNetBufferList(Receiver); if (NetBufferList != NULL) { PNET_BUFFER NetBuffer; - Receiver->GetList[Index] = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = NULL; NET_BUFFER_LIST_INFO(NetBufferList, Ieee8021QNetBufferListInfo) = NULL; NET_BUFFER_LIST_INFO(NetBufferList, NetBufferListHashInfo) = NULL; @@ -129,21 +173,10 @@ __ReceiverReleaseNetBufferList( Cookie = ListReserved->Cookie; ListReserved->Cookie = NULL; - if (Cache) { - PNET_BUFFER_LIST Old; - PNET_BUFFER_LIST New; - - ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL); - - do { - Old = Receiver->PutList; - - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = Old; - New = NetBufferList; - } while (InterlockedCompareExchangePointer(&Receiver->PutList, New, Old) != Old); - } else { + if (Cache) + __ReceiverPutNetBufferList(Receiver, NetBufferList); + else NdisFreeNetBufferList(NetBufferList); - } return Cookie; } @@ -272,24 +305,36 @@ fail1: } static VOID -__ReceiverPushPacket( +__ReceiverPushPackets( IN PXENNET_RECEIVER Receiver, - IN PNET_BUFFER_LIST NetBufferList + IN ULONG Index ) { ULONG Flags; LONG InNDIS; + PXENNET_RECEIVER_QUEUE Queue; + PNET_BUFFER_LIST NetBufferList; + ULONG Count; InNDIS = InterlockedIncrement(&Receiver->InNDIS); - Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL; + 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]; + + NetBufferList = Queue->Head; + Count = Queue->Count; + + RtlZeroMemory(Queue, sizeof (XENNET_RECEIVER_QUEUE)); + NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter), NetBufferList, NDIS_DEFAULT_PORT_NUMBER, - 1, + Count, Flags); if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES) @@ -416,11 +461,14 @@ ReceiverQueuePacket( IN USHORT TagControlInformation, IN PXENVIF_PACKET_INFO Info, IN PXENVIF_PACKET_HASH Hash, + IN BOOLEAN More, IN PVOID Cookie ) { PXENVIF_VIF_INTERFACE VifInterface; PNET_BUFFER_LIST NetBufferList; + ULONG Index; + PXENNET_RECEIVER_QUEUE Queue; VifInterface = AdapterGetVifInterface(Receiver->Adapter); @@ -434,14 +482,28 @@ ReceiverQueuePacket( Info, Hash, Cookie); - - if (NetBufferList != NULL) { - __ReceiverPushPacket(Receiver, NetBufferList); - } else { + if (NetBufferList == NULL) { XENVIF_VIF(ReceiverReturnPacket, VifInterface, Cookie); + return; } + + Index = KeGetCurrentProcessorNumberEx(NULL); + + Queue = &Receiver->Queue[Index]; + + if (Queue->Head == NULL) { + ASSERT3U(Queue->Count, ==, 0); + Queue->Head = Queue->Tail = NetBufferList; + } else { + NET_BUFFER_LIST_NEXT_NBL(Queue->Tail) = NetBufferList; + Queue->Tail = NetBufferList; + } + Queue->Count++; + + if (!More) + __ReceiverPushPackets(Receiver, Index); } PXENVIF_VIF_OFFLOAD_OPTIONS diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h index 73ffc7e..e753095 100644 --- a/src/xennet/receiver.h +++ b/src/xennet/receiver.h @@ -66,6 +66,7 @@ ReceiverQueuePacket( IN USHORT TagControlInformation, IN PXENVIF_PACKET_INFO Info, IN PXENVIF_PACKET_HASH Hash, + IN BOOLEAN More, IN PVOID Cookie ); diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c index 432198c..72f54ed 100644 --- a/src/xennet/transmitter.c +++ b/src/xennet/transmitter.c @@ -267,6 +267,7 @@ TransmitterSendNetBufferLists( XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions; USHORT TagControlInformation; USHORT MaximumSegmentSize; + XENVIF_PACKET_HASH Hash; ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; @@ -278,52 +279,51 @@ TransmitterSendNetBufferLists( OffloadOptions.Value &= Transmitter->OffloadOptions.Value; - ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList); - RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED)); + switch (NET_BUFFER_LIST_GET_HASH_FUNCTION(NetBufferList)) { + case NdisHashFunctionToeplitz: + Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ; + break; - __TransmitterGetNetBufferList(Transmitter, NetBufferList); + default: + Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE; + break; + } - NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); - while (NetBuffer != NULL) { - PNET_BUFFER NetBufferListNext = NET_BUFFER_NEXT_NB(NetBuffer); - PVOID Cookie = NetBufferList; - XENVIF_PACKET_HASH Hash; - NTSTATUS status; + switch (NET_BUFFER_LIST_GET_HASH_TYPE(NetBufferList)) { + case NDIS_HASH_IPV4: + Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4; + break; - __TransmitterGetNetBufferList(Transmitter, NetBufferList); + case NDIS_HASH_TCP_IPV4: + Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4_TCP; + break; - switch (NET_BUFFER_LIST_GET_HASH_FUNCTION(NetBufferList)) { - case NdisHashFunctionToeplitz: - Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ; - break; + case NDIS_HASH_IPV6: + Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6; + break; - default: - Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE; - break; - } + case NDIS_HASH_TCP_IPV6: + Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6_TCP; + break; - switch (NET_BUFFER_LIST_GET_HASH_TYPE(NetBufferList)) { - case NDIS_HASH_IPV4: - Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4; + default: break; + } - case NDIS_HASH_TCP_IPV4: - Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV4_TCP; - break; + Hash.Value = NET_BUFFER_LIST_GET_HASH_VALUE(NetBufferList); - case NDIS_HASH_IPV6: - Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6; - break; + ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList); + RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED)); - case NDIS_HASH_TCP_IPV6: - Hash.Type = XENVIF_PACKET_HASH_TYPE_IPV6_TCP; - break; + __TransmitterGetNetBufferList(Transmitter, NetBufferList); - default: - break; - } + NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + while (NetBuffer != NULL) { + PNET_BUFFER NetBufferListNext = NET_BUFFER_NEXT_NB(NetBuffer); + PVOID Cookie = NetBufferList; + NTSTATUS status; - Hash.Value = NET_BUFFER_LIST_GET_HASH_VALUE(NetBufferList); + __TransmitterGetNetBufferList(Transmitter, NetBufferList); status = XENVIF_VIF(TransmitterQueuePacket, AdapterGetVifInterface(Transmitter->Adapter), @@ -334,6 +334,7 @@ TransmitterSendNetBufferLists( MaximumSegmentSize, TagControlInformation, &Hash, + (NetBufferListNext != NULL) ? TRUE : FALSE, Cookie); if (!NT_SUCCESS(status)) { __TransmitterReturnPacket(Transmitter, Cookie, -- 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 |