]> xenbits.xensource.com Git - people/pauldu/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>
Tue, 19 Jan 2016 11:21:28 +0000 (11:21 +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 08c64133df3d0e9404e3dacfe6eeac19ba36ac4b..863dbd77d5c2751813225616db5ee1ccb8135e0e 100644 (file)
@@ -89,6 +89,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;