|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 1/2] xennet: improve NBL batching receive path
Raise NblBatchMax default to 32 (max 64). Split batches at
EtherType boundaries and set NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE per
batch. Fix __ReceiverPushPackets: move KeMemoryBarrier before Returned/
Indicated reads, and return early when queue is empty.
Signed-off-by: david ambu <david.preetham@xxxxxxxxxx>
---
src/xennet.inf | 6 +++
src/xennet/adapter.c | 13 +++++
src/xennet/adapter.h | 8 ++++
src/xennet/receiver.c | 108 +++++++++++++++++++++++++++++++-----------
4 files changed, 108 insertions(+), 27 deletions(-)
diff --git a/src/xennet.inf b/src/xennet.inf
index 55e11a2..79730e8 100644
--- a/src/xennet.inf
+++ b/src/xennet.inf
@@ -186,6 +186,11 @@ HKR, Ndi\params\*NumRSSQueues, Default,
0, "8"
HKR, Ndi\params\*NumRSSQueues, Min, 0, "1"
HKR, Ndi\params\*NumRSSQueues, Max, 0, "8"
+HKR, Ndi\Params\NblBatchMax, ParamDesc,
0, %NblBatchMax%
+HKR, Ndi\Params\NblBatchMax, Type,
0, "int"
+HKR, Ndi\Params\NblBatchMax, Default,
0, "32"
+HKR, Ndi\Params\NblBatchMax, Min,
0, "1"
+HKR, Ndi\Params\NblBatchMax, Max,
0, "64"
[XenNet_Inst.Services]
AddService=xennet,0x02,XenNet_Service,XenNet_EventLog
@@ -248,6 +253,7 @@ Enabled="Enabled"
Enabled-Rx="Rx Enabled"
Enabled-Tx="Tx Enabled"
Enabled-TxRx="Rx & Tx Enabled"
+NblBatchMax="Max Receive Indicate NBLS"
SERVICE_BOOT_START=0x0
SERVICE_SYSTEM_START=0x1
diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index f79c0c8..6e5a95a 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -63,6 +63,7 @@ typedef struct _PROPERTIES {
int lrov6;
int rss;
int numrssqueues;
+ int nblbatchmax;
} PROPERTIES, *PPROPERTIES;
typedef struct _XENNET_RSS {
@@ -1480,6 +1481,17 @@ AdapterGetHandle(
return Adapter->NdisAdapterHandle;
}
+ULONG
+AdapterGetNblMaxBatchSize(
+ IN PXENNET_ADAPTER Adapter
+ )
+{
+ ULONG val = (ULONG)Adapter->Properties.nblbatchmax;
+ if (val == 0 || val > NBL_BATCH_SIZE_MAX)
+ return NBL_BATCH_SIZE_DEFAULT;
+ return val;
+}
+
PXENVIF_VIF_INTERFACE
AdapterGetVifInterface(
IN PXENNET_ADAPTER Adapter
@@ -2939,6 +2951,7 @@ AdapterGetAdvancedSettings(
READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue",
1, Handle);
READ_PROPERTY(Adapter->Properties.rss, L"*RSS", 1, Handle);
READ_PROPERTY(Adapter->Properties.numrssqueues, L"*NumRSSQueues", 8,
Handle);
+ READ_PROPERTY(Adapter->Properties.nblbatchmax, L"NblBatchMax",
NBL_BATCH_SIZE_DEFAULT, Handle);
NdisCloseConfiguration(Handle);
diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
index 2ea0345..a54cb4d 100644
--- a/src/xennet/adapter.h
+++ b/src/xennet/adapter.h
@@ -121,4 +121,12 @@ AdapterQueryInformation(
IN PNDIS_OID_REQUEST Request
);
+#define NBL_BATCH_SIZE_DEFAULT 32
+#define NBL_BATCH_SIZE_MAX 64
+
+extern ULONG
+AdapterGetNblMaxBatchSize(
+ IN PXENNET_ADAPTER Adapter
+ );
+
#endif // _XENNET_ADAPTER_H_
diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
index b4cf4f0..c46e6a3 100644
--- a/src/xennet/receiver.c
+++ b/src/xennet/receiver.c
@@ -34,6 +34,7 @@
#include <procgrp.h>
#include <tcpip.h>
#include <xen.h>
+#include <ethernet.h>
#include "util.h"
#include "receiver.h"
@@ -64,6 +65,7 @@ struct _XENNET_RECEIVER {
typedef struct _NET_BUFFER_LIST_RESERVED {
PVOID Cookie;
+ USHORT EtherType;
} NET_BUFFER_LIST_RESERVED, *PNET_BUFFER_LIST_RESERVED;
C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST,
MiniportReserved));
@@ -120,6 +122,7 @@ __ReceiverAllocateNetBufferList(
IN PMDL Mdl,
IN ULONG Offset,
IN ULONG Length,
+ IN PXENVIF_PACKET_INFO Info,
IN PVOID Cookie
)
{
@@ -156,10 +159,25 @@ __ReceiverAllocateNetBufferList(
if (NetBufferList != NULL) {
PNET_BUFFER_LIST_RESERVED ListReserved;
+ USHORT EtherType = 0;
+
+ if (Info->EthernetHeader.Length != 0) {
+ PUCHAR Buffer;
+ PETHERNET_HEADER EthernetHeader;
+
+ Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority |
MdlMappingNoExecute);
+ if (Buffer != NULL) {
+ EthernetHeader = (PETHERNET_HEADER)(Buffer + Offset +
Info->EthernetHeader.Offset);
+ EtherType = ETHERNET_HEADER_IS_TAGGED(EthernetHeader) ?
+ EthernetHeader->Tagged.TypeOrLength :
+ EthernetHeader->Untagged.TypeOrLength;
+ }
+ }
ListReserved =
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
ASSERT3P(ListReserved->Cookie, ==, NULL);
ListReserved->Cookie = Cookie;
+ ListReserved->EtherType = EtherType;
}
return NetBufferList;
@@ -178,6 +196,7 @@ __ReceiverReleaseNetBufferList(
ListReserved =
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
Cookie = ListReserved->Cookie;
ListReserved->Cookie = NULL;
+ ListReserved->EtherType = 0;
if (Cache)
__ReceiverPutNetBufferList(Receiver, NetBufferList);
@@ -240,12 +259,12 @@ __ReceiverReceivePacket(
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
UNREFERENCED_PARAMETER(MaximumSegmentSize);
- UNREFERENCED_PARAMETER(Info);
NetBufferList = __ReceiverAllocateNetBufferList(Receiver,
Mdl,
Offset,
Length,
+ Info,
Cookie);
if (NetBufferList == NULL)
goto fail1;
@@ -328,9 +347,11 @@ fail1:
return NULL;
}
-static FORCEINLINE VOID __IndicateReceiveNetBufferLists(
+
+static FORCEINLINE VOID
+__IndicateReceiveNetBufferLists(
IN PXENNET_RECEIVER Receiver,
- IN PNET_BUFFER_LIST NetBufferLists,
+ IN PNET_BUFFER_LIST Remaining,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG NumberOfNetBufferLists,
IN ULONG ReceiveFlags
@@ -339,39 +360,70 @@ static FORCEINLINE VOID __IndicateReceiveNetBufferLists(
PXENNET_ADAPTER Adapter = Receiver->Adapter;
NDIS_HANDLE MiniportAdapterHandle = AdapterGetHandle(Adapter);
PXENVIF_VIF_INTERFACE VifInterface;
- ULONG Count;
-
- VifInterface = AdapterGetVifInterface(Receiver->Adapter);
+ ULONG Count = 0;
+ ULONG NblMaxBatch = AdapterGetNblMaxBatchSize(Adapter);
+
+ while (Remaining != NULL) {
+ PNET_BUFFER_LIST BatchTail = Remaining;
+ PNET_BUFFER_LIST NextNbl;
+ ULONG BatchCount = 1;
+ ULONG BatchFlags;
+ USHORT FirstEth;
+
+ FirstEth = ((PNET_BUFFER_LIST_RESERVED)
+ NET_BUFFER_LIST_MINIPORT_RESERVED(Remaining))->EtherType;
+ NextNbl = NET_BUFFER_LIST_NEXT_NBL(BatchTail);
+
+ while (NextNbl != NULL && BatchCount < NblMaxBatch) {
+ USHORT CurEth;
+ CurEth = ((PNET_BUFFER_LIST_RESERVED)
+ NET_BUFFER_LIST_MINIPORT_RESERVED(NextNbl))->EtherType;
+ if (CurEth != FirstEth)
+ break;
+ BatchTail = NextNbl;
+ NextNbl = NET_BUFFER_LIST_NEXT_NBL(BatchTail);
+ BatchCount++;
+ }
- Count = 0;
- while (NetBufferLists != NULL) {
- PNET_BUFFER_LIST Next;
+ NET_BUFFER_LIST_NEXT_NBL(BatchTail) = NULL;
- Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferLists);
- NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) = NULL;
+ BatchFlags = ReceiveFlags;
+ if (FirstEth != 0)
+ BatchFlags |= NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE;
+ else
+ BatchFlags &= ~NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE;
NdisMIndicateReceiveNetBufferLists(MiniportAdapterHandle,
- NetBufferLists,
+ Remaining,
PortNumber,
- 1,
- ReceiveFlags);
+ BatchCount,
+ BatchFlags);
- if (ReceiveFlags & NDIS_RECEIVE_FLAGS_RESOURCES) {
- PVOID Cookie;
+ if (BatchFlags & NDIS_RECEIVE_FLAGS_RESOURCES) {
+ PNET_BUFFER_LIST Current = Remaining;
- Cookie = __ReceiverReleaseNetBufferList(Receiver,
- NetBufferLists,
- FALSE);
+ VifInterface = AdapterGetVifInterface(Receiver->Adapter);
- XENVIF_VIF(ReceiverReturnPacket,
- VifInterface,
- Cookie);
+ while (Current != NULL) {
+ PNET_BUFFER_LIST Next = NET_BUFFER_LIST_NEXT_NBL(Current);
+ NET_BUFFER_LIST_NEXT_NBL(Current) = NULL;
- (VOID) InterlockedIncrement(&Receiver->Returned);
+ PVOID Cookie = __ReceiverReleaseNetBufferList(Receiver,
+ Current,
+ FALSE);
+
+ XENVIF_VIF(ReceiverReturnPacket,
+ VifInterface,
+ Cookie);
+
+ Current = Next;
+ }
+
+ (VOID)InterlockedAdd(&Receiver->Returned, BatchCount);
}
- Count++;
- NetBufferLists = Next;
+ Count += BatchCount;
+ Remaining = NextNbl;
}
ASSERT3U(Count, ==, NumberOfNetBufferLists);
}
@@ -402,12 +454,14 @@ __ReceiverPushPackets(
KeReleaseSpinLockFromDpcLevel(&Queue->Lock);
- (VOID) InterlockedAdd(&Receiver->Indicated, Count);
+ if (Count == 0)
+ return;
- Returned = Receiver->Returned;
+ (VOID) InterlockedAdd(&Receiver->Indicated, Count);
KeMemoryBarrier();
+ Returned = Receiver->Returned;
Indicated = Receiver->Indicated;
Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL |
--
2.51.0.windows.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |