]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Shim NdisMIndicateReceiveNetBufferLists() to avoid multiple indications
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 22 Sep 2016 10:01:03 +0000 (11:01 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 22 Sep 2016 10:09:40 +0000 (11:09 +0100)
It seems that, on some versions of Windows, something in the network
stack does not work properly with receive indications of more than
one NET_BUFFER_LIST at once.

This patch shims NdisMIndicateReceiveNetBufferLists() to iterate over
a chain of NET_BUFFER_LISTS and indicate them separately. Hopefully
this workaround can be removed in future.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xennet/receiver.c

index 86d2ffb43cecc7374c522b7a68b476d0c76741a2..36a153b83ae3bd75d11d2466de31a8f0cfba6d96 100644 (file)
@@ -323,6 +323,35 @@ fail1:
     return NULL;
 }
 
+static FORCEINLINE VOID __IndicateReceiveNetBufferLists(
+    IN  NDIS_HANDLE         MiniportAdapterHandle,
+    IN  PNET_BUFFER_LIST    NetBufferLists,
+    IN  NDIS_PORT_NUMBER    PortNumber,
+    IN  ULONG               NumberOfNetBufferLists,
+    IN  ULONG               ReceiveFlags
+    )
+{
+    ULONG                   Count;
+
+    Count = 0;
+    while (NetBufferLists != NULL) {
+        PNET_BUFFER_LIST        Next;
+
+        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferLists);
+        NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) = NULL;
+
+        NdisMIndicateReceiveNetBufferLists(MiniportAdapterHandle,
+                                           NetBufferLists,
+                                           PortNumber,
+                                           1,
+                                           ReceiveFlags);
+
+        Count++;
+        NetBufferLists = Next;
+    }
+    ASSERT3U(Count, ==, NumberOfNetBufferLists);
+}
+
 static VOID
 __ReceiverPushPackets(
     IN  PXENNET_RECEIVER    Receiver,
@@ -357,11 +386,11 @@ __ReceiverPushPackets(
     if (Indicated - Returned > IN_NDIS_MAX)
         Flags |= NDIS_RECEIVE_FLAGS_RESOURCES;
 
-    NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter),
-                                       NetBufferList,
-                                       NDIS_DEFAULT_PORT_NUMBER,
-                                       Count,
-                                       Flags);
+    __IndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter),
+                                    NetBufferList,
+                                    NDIS_DEFAULT_PORT_NUMBER,
+                                    Count,
+                                    Flags);
 
     if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES)
         (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE);