[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.