]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Update to XENVIF_VIF interface version 8
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 20 Sep 2016 13:19:33 +0000 (14:19 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Tue, 20 Sep 2016 13:26:05 +0000 (14:26 +0100)
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@citrix.com>
include/vif_interface.h
src/xennet.inf
src/xennet/adapter.c
src/xennet/receiver.c
src/xennet/receiver.h

index 4a9598917f4fb6f28f9720af2d419f8cf44e0b19..38872bc28c33f0e198e2e3a502fea01d3c724850 100644 (file)
@@ -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
index d50e6b37b3656368f6120a8099302023d9096245..d38b0c22c08ce0b643ad2d7737a803d1c6620480 100644 (file)
@@ -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
index 6587db4a1007c8969a5b57b985beb6b96e8d25c0..9a062e1161c12d2877ce4ebd89ef1b71fa77a9bb 100644 (file)
@@ -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,
index fc11344de3e5f9b8911c3750ec385b475a9d8986..a814d57b6e405a53d73fefb07afd3d56e514bdc4 100644 (file)
@@ -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);
 }
index e7530959f56838aa4c942db7703e575737f6e973..5b59431ed65ea03ff92a3c395b4dabfd3e726890 100644 (file)
@@ -58,6 +58,7 @@ ReceiverReturnNetBufferLists(
 extern VOID
 ReceiverQueuePacket(
     IN  PXENNET_RECEIVER                Receiver,
+    IN  ULONG                           Index,
     IN  PMDL                            Mdl,
     IN  ULONG                           Offset,
     IN  ULONG                           Length,