]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Make transmitter robust against a possible completion race
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 19 Jan 2016 11:21:28 +0000 (11:21 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 22 Jan 2016 12:57:53 +0000 (12:57 +0000)
It's possible that a transmission invoked on one CPU may complete on another
before the transmission invocation as finished. Therefore, once we have queued
a NET_BUFFER for transmission we should not use it's metadata again (including
the 'next' pointer).

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

index 955b2b203f7e34121526c118f8b173b5da5801fb..6ce82895ffe338a8cbd68866cbdc57ac9a565d57 100644 (file)
@@ -90,6 +90,8 @@ __ReceiverAllocateNetBufferList(
         NET_BUFFER_DATA_OFFSET(NetBuffer) = Offset;
         NET_BUFFER_DATA_LENGTH(NetBuffer) = Length;
         NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer) = Offset;
+
+        ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL);
     } else {
         NetBufferList = NdisAllocateNetBufferAndNetBufferList(Receiver->NetBufferListPool,
                                                               0,
index b5e110a707a56421d89d51547fe86d29e5b73f3b..91ed5f2cecf164d32f000f02fed7e3f80c227061 100644 (file)
@@ -250,11 +250,12 @@ TransmitterSendNetBufferLists(
 
         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;
 
-            ListReserved->Reference++;
+            InterlockedIncrement(&ListReserved->Reference);
 
             Hash.Algorithm = XENVIF_PACKET_HASH_ALGORITHM_NONE;
 
@@ -274,7 +275,7 @@ TransmitterSendNetBufferLists(
                 break;
             }
 
-            NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer);
+            NetBuffer = NetBufferListNext;
         }
 
         NetBufferList = ListNext;