[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] Introduce per-dpc rate limits for XenVif / XeNet Rx path.


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Martin Harvey <Martin.Harvey@xxxxxxxxxx>
  • Date: Fri, 13 May 2022 11:24:44 +0100
  • Authentication-results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Martin Harvey <Martin.Harvey@xxxxxxxxxx>, Martin Harvey <martin.harvey@xxxxxxxxxx>
  • Delivery-date: Fri, 13 May 2022 10:25:04 +0000
  • Ironport-data: A9a23:fZrm9Kt71VPyi8pfvJ2wdR6Z/+fnVAJeMUV32f8akzHdYApBsoF/q tZmKWiCOPyNNzHzftpzPtnjpE8Hv5bVztBhHlM+/HowRXgS+JbJXdiXEBz9bniYRiHhoOOLz Cm8hv3odp1coqr0/0/1WlTZhSAgk/nOHNIQMcacUsxLbVYMpBwJ1FQywobVvqYy2YLjW17U4 ouryyHiEATNNwBcYzp8B52r8HuDjNyq0N/PlgVjDRzjlAa2e0g9VPrzF4noR5fLatA88tqBb /TC1NmEElbxpH/BPD8HfoHTKSXmSpaKVeSHZ+E/t6KK2nCurQRquko32WZ1he66RFxlkvgoo Oihu6BcRi8KHrPe3+FDFCBKUAxOMqJDybbqAkmG5Jn7I03uKxMAwt1rBUAye4YZ5vx2ESdF8 vlwxDIlN07ZwbjsmfTiF7cq1p9LwMrDZevzvlllxCvFDPBgQZnZXajbzdRZwC0xloZFGvO2i 88xNmM1N0idMk0n1lE/CpwFx+6Jo0fDfiBmlXuuiYd0z2Hx5VkkuFTqGIWMIYHbLSlPpW6Hp 2SD53q8DhwEOdi3zTue7mnqluLJhTn8Wo8ZCPu/7PECvbGI7jVNUltMDwL9+KTnzB7lMz5CF 6AK0gkOs7p18RLsd8u+ci23r3u1tzM/auMFRoXW9zqx4qbT5g+YAE0NQThAdMEquacKeNA66 rOat4i3XGIy6dV5XVrYr+7J9m3qZUD5OEdYPUc5oR05D84PSW3ZpjbGVZ5dHaG8lbUZ8hmgk mnR/EDSa1j+5PPnNplXH3ia21pARbCTF2bZAzk7uUr/tmtEiHaNPdDA1LQixa8owHylZleAp mMYvMOV8foDC5qA/ATUHrhXR+Hxu6ndaGeE6bKKI3XG3273k0NPgKgKuG0uTKuXGphslcDVj L/75loKuc470IqCZq5reYOhY/nGPoC7fekJosv8N4IUCrAoLVfv1Hg3NSa4gjG2+GBxwP5XB HtuWZv1ZZrsIf8/nGTeqiZ0+eJD+x3SMkuJG8+hk0T8ger2ibz8Ye5tDWZip9sRtMusyDg5O f4GXydW432ziNHDXxQ=
  • Ironport-hdrordr: A9a23:9s1PBKjfbK4Xfm8G3HxTPRcNQXBQXtAji2hC6mlwRA09TySZ// rAoB19726QtN9xYgBGpTnuAsi9qB/nmKKdgrNhX4tKPjOHhILAFugLhuHfKlXbaknDH4Vmu5 uIHZITNDSJNykYsfrH
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

This patch allows XenNet to keep track of how many packets have
been processed in a "batch" (per DPC), and to ask XenVif to stop
the current batch once some predefined limit has been met.

Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx>
---
 include/revision.h      |   3 +-
 include/vif_interface.h |   7 ++-
 src/xenvif/receiver.c   |  79 ++++++++++++++++++-------
 src/xenvif/vif.c        | 124 ++++++++++++++++++++++++++++++++++------
 src/xenvif/vif.h        |   2 +-
 5 files changed, 173 insertions(+), 42 deletions(-)

diff --git a/include/revision.h b/include/revision.h
index 39476b2..475700d 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -44,6 +44,7 @@
     DEFINE_REVISION(0x0800000C,  1,  7,  2,  1),    \
     DEFINE_REVISION(0x0800000D,  1,  8,  2,  1),    \
     DEFINE_REVISION(0x09000000,  1,  8,  2,  1),    \
-    DEFINE_REVISION(0x09000001,  2,  8,  2,  1)
+    DEFINE_REVISION(0x09000001,  2,  8,  2,  1),    \
+    DEFINE_REVISION(0x09000002,  2,  9,  2,  1)
 
 #endif  // _REVISION_H
diff --git a/include/vif_interface.h b/include/vif_interface.h
index 20de314..c034657 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -928,7 +928,10 @@ struct _XENVIF_VIF_INTERFACE_V8 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V8 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+/* V9 is exactly the same as V8 */
+typedef struct _XENVIF_VIF_INTERFACE_V8 XENVIF_VIF_INTERFACE_V9;
+
+typedef XENVIF_VIF_INTERFACE_V9 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -939,6 +942,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V8 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    6
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    8
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    9
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index 505505e..0c1be81 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -99,6 +99,8 @@ typedef struct _XENVIF_RECEIVER_RING {
     BOOLEAN                     Connected;
     BOOLEAN                     Enabled;
     BOOLEAN                     Stopped;
+    BOOLEAN                     Backpressured;
+    BOOLEAN                     FinalFlush;
     XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
     ULONG                       BackfillSize;
     PXENBUS_DEBUG_CALLBACK      DebugCallback;
@@ -1338,43 +1340,53 @@ __ReceiverRingSwizzle(
     PXENVIF_VIF_CONTEXT         Context;
     LIST_ENTRY                  List;
     PLIST_ENTRY                 ListEntry;
+    BOOLEAN                     AllFlushed;
+    BOOLEAN                     NdisFinishedBatch;
 
     Receiver = Ring->Receiver;
     Frontend = Receiver->Frontend;
     Context = PdoGetVifContext(FrontendGetPdo(Frontend));
+    AllFlushed = TRUE;
+    NdisFinishedBatch = FALSE;
 
     InitializeListHead(&List);
 
-    ListEntry = InterlockedExchangePointer(&Ring->PacketQueue, NULL);
+    if (IsListEmpty(&Ring->PacketComplete) || Ring->FinalFlush)
+    {
+        ListEntry = InterlockedExchangePointer(&Ring->PacketQueue, NULL);
 
-    // Packets are held in the queue in reverse order so that the most
-    // recent is always head of the list. This is necessary to allow
-    // addition to the list to be done atomically.
+        // Packets are held in the queue in reverse order so that the most
+        // recent is always head of the list. This is necessary to allow
+        // addition to the list to be done atomically.
 
-    while (ListEntry != NULL) {
-        PLIST_ENTRY NextEntry;
+        while (ListEntry != NULL) {
+            PLIST_ENTRY NextEntry;
 
-        NextEntry = ListEntry->Blink;
-        ListEntry->Flink = ListEntry->Blink = ListEntry;
+            NextEntry = ListEntry->Blink;
+            ListEntry->Flink = ListEntry->Blink = ListEntry;
 
-        InsertHeadList(&List, ListEntry);
+            InsertHeadList(&List, ListEntry);
 
-        ListEntry = NextEntry;
-    }
+            ListEntry = NextEntry;
+        }
 
-    while (!IsListEmpty(&List)) {
-        PXENVIF_RECEIVER_PACKET Packet;
+        while (!IsListEmpty(&List)) {
+            PXENVIF_RECEIVER_PACKET Packet;
 
-        ListEntry = RemoveHeadList(&List);
-        ASSERT3P(ListEntry, !=, &List);
+            ListEntry = RemoveHeadList(&List);
+            ASSERT3P(ListEntry, !=, &List);
 
-        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+            RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
 
-        Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, 
ListEntry);
-        ReceiverRingProcessPacket(Ring, Packet);
+            Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, 
ListEntry);
+            ReceiverRingProcessPacket(Ring, Packet);
+        }
+    } else {
+        AllFlushed = FALSE;
     }
 
-    while (!IsListEmpty(&Ring->PacketComplete)) {
+    while (!IsListEmpty(&Ring->PacketComplete) &&
+           (!NdisFinishedBatch || Ring->FinalFlush)) {
         PXENVIF_RECEIVER_PACKET Packet;
         PXENVIF_PACKET_INFO     Info;
         PUCHAR                  BaseVa;
@@ -1527,7 +1539,7 @@ __ReceiverRingSwizzle(
 
         (VOID) InterlockedIncrement(&Receiver->Loaned);
 
-        VifReceiverQueuePacket(Context,
+        NdisFinishedBatch = VifReceiverQueuePacket(Context,
                                Ring->Index,
                                &Packet->Mdl,
                                Packet->Offset,
@@ -1537,9 +1549,28 @@ __ReceiverRingSwizzle(
                                Packet->TagControlInformation,
                                &Packet->Info,
                                &Packet->Hash,
-                               !IsListEmpty(&Ring->PacketComplete) ? TRUE : 
FALSE,
+                               !IsListEmpty(&Ring->PacketComplete), /* Keep 
this in - resets counts in xennet */
                                Packet);
     }
+
+    if (!IsListEmpty(&Ring->PacketComplete))
+        AllFlushed = FALSE;
+
+    if (!AllFlushed) {
+        //Re-run remainder from back of DPC queue.
+        Ring->Backpressured = TRUE;
+        if (KeInsertQueueDpc(&Ring->QueueDpc, NULL, NULL))
+            Ring->QueueDpcs++;
+    } else {
+        if ((Ring->Backpressured) && !Ring->FinalFlush) {
+            //Not any more - restart dataflow from initial ring poll.
+            Ring->Backpressured = FALSE;
+
+            //PollDpc zeroed before final flush, don't queue it here.
+            if (KeInsertQueueDpc(&Ring->PollDpc, NULL, NULL))
+                Ring->PollDpcs++;
+        }
+    }
 }
 
 static FORCEINLINE VOID
@@ -1990,7 +2021,7 @@ ReceiverRingPoll(
 
     Count = 0;
 
-    if (!Ring->Enabled)
+    if (!Ring->Enabled || (Ring->Backpressured && !Ring->FinalFlush))
         goto done;
 
     for (;;) {
@@ -2963,8 +2994,12 @@ __ReceiverRingTeardown(
     Ring->BackfillSize = 0;
     Ring->OffloadOptions.Value = 0;
 
+    Ring->FinalFlush = TRUE;
+    KeInsertQueueDpc(&Ring->QueueDpc, NULL, NULL);
     KeFlushQueuedDpcs();
     RtlZeroMemory(&Ring->QueueDpc, sizeof (KDPC));
+    Ring->Backpressured = FALSE;
+    Ring->FinalFlush = FALSE;
 
     ThreadAlert(Ring->WatchdogThread);
     ThreadJoin(Ring->WatchdogThread);
diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
index 69ced78..b026e5b 100644
--- a/src/xenvif/vif.c
+++ b/src/xenvif/vif.c
@@ -918,6 +918,36 @@ static struct _XENVIF_VIF_INTERFACE_V8 
VifInterfaceVersion8 = {
     VifMacQueryFilterLevel
 };
 
+static XENVIF_VIF_INTERFACE_V9 VifInterfaceVersion9 = {
+    { sizeof (XENVIF_VIF_INTERFACE_V9), 9, NULL, NULL, NULL },
+    VifAcquire,
+    VifRelease,
+    VifEnable,
+    VifDisable,
+    VifQueryStatistic,
+    VifQueryRingCount,
+    VifUpdateHashMapping,
+    VifReceiverReturnPacket,
+    VifReceiverSetOffloadOptions,
+    VifReceiverSetBackfillSize,
+    VifReceiverQueryRingSize,
+    VifReceiverSetHashAlgorithm,
+    VifReceiverQueryHashCapabilities,
+    VifReceiverUpdateHashParameters,
+    VifTransmitterQueuePacket,
+    VifTransmitterQueryOffloadOptions,
+    VifTransmitterQueryLargePacketSize,
+    VifTransmitterQueryRingSize,
+    VifMacQueryState,
+    VifMacQueryMaximumFrameSize,
+    VifMacQueryPermanentAddress,
+    VifMacQueryCurrentAddress,
+    VifMacQueryMulticastAddresses,
+    VifMacSetMulticastAddresses,
+    VifMacSetFilterLevel,
+    VifMacQueryFilterLevel
+};
+
 NTSTATUS
 VifInitialize(
     IN  PXENVIF_PDO         Pdo,
@@ -1033,6 +1063,23 @@ VifGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 9: {
+        XENVIF_VIF_INTERFACE_V9 *VifInterface;
+
+        VifInterface = (XENVIF_VIF_INTERFACE_V9 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (XENVIF_VIF_INTERFACE_V9))
+            break;
+
+        *VifInterface = VifInterfaceVersion9;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
@@ -1133,7 +1180,7 @@ __VifReceiverQueuePacketVersion7(
 }
 
 static FORCEINLINE VOID
-__VifReceiverQueuePacket(
+__VifReceiverQueuePacketVersion8(
     IN  PXENVIF_VIF_CONTEXT             Context,
     IN  ULONG                           Index,
     IN  PMDL                            Mdl,
@@ -1164,7 +1211,42 @@ __VifReceiverQueuePacket(
 
 }
 
-VOID
+static FORCEINLINE BOOLEAN
+__VifReceiverQueuePacket(
+    IN  PXENVIF_VIF_CONTEXT             Context,
+    IN  ULONG                           Index,
+    IN  PMDL                            Mdl,
+    IN  ULONG                           Offset,
+    IN  ULONG                           Length,
+    IN  XENVIF_PACKET_CHECKSUM_FLAGS    Flags,
+    IN  USHORT                          MaximumSegmentSize,
+    IN  USHORT                          TagControlInformation,
+    IN  PXENVIF_PACKET_INFO             Info,
+    IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
+    IN  PVOID                           Cookie
+    )
+{
+    BOOLEAN Finished = FALSE;
+    Context->Callback(Context->Argument,
+                      XENVIF_RECEIVER_QUEUE_PACKET,
+                      Index,
+                      Mdl,
+                      Offset,
+                      Length,
+                      Flags,
+                      MaximumSegmentSize,
+                      TagControlInformation,
+                      Info,
+                      Hash,
+                      More,
+                      Cookie,
+                      &Finished);
+    return Finished;
+}
+
+
+BOOLEAN /* Returns NDIS finished batch for this DPC */
 VifReceiverQueuePacket(
     IN  PXENVIF_VIF_CONTEXT             Context,
     IN  ULONG                           Index,
@@ -1181,6 +1263,7 @@ VifReceiverQueuePacket(
     )
 {
     KIRQL                               Irql;
+    BOOLEAN                             Finished = FALSE;
 
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
@@ -1216,7 +1299,22 @@ VifReceiverQueuePacket(
         break;
 
     case 8:
-        __VifReceiverQueuePacket(Context,
+        __VifReceiverQueuePacketVersion8(Context,
+                                 Index,
+                                 Mdl,
+                                 Offset,
+                                 Length,
+                                 Flags,
+                                 MaximumSegmentSize,
+                                 TagControlInformation,
+                                 Info,
+                                 Hash,
+                                 More,
+                                 Cookie);
+        break;
+
+    case 9:
+        Finished = __VifReceiverQueuePacket(Context,
                                  Index,
                                  Mdl,
                                  Offset,
@@ -1236,6 +1334,8 @@ VifReceiverQueuePacket(
     }
 
     KeLowerIrql(Irql);
+
+    return Finished;
 }
 
 VOID
@@ -1245,20 +1345,12 @@ VifTransmitterReturnPacket(
     IN  PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion
     )
 {
-    switch (Context->Version) {
-    case 6:
-    case 7:
-    case 8:
-        Context->Callback(Context->Argument,
-                          XENVIF_TRANSMITTER_RETURN_PACKET,
-                          Cookie,
-                          Completion);
-        break;
+    BUG_ON(Context->Version < 6);
 
-    default:
-        ASSERT(FALSE);
-        break;
-    }
+    Context->Callback(Context->Argument,
+                        XENVIF_TRANSMITTER_RETURN_PACKET,
+                        Cookie,
+                        Completion);
 }
 
 PXENVIF_THREAD
diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h
index b83a767..054cef1 100644
--- a/src/xenvif/vif.h
+++ b/src/xenvif/vif.h
@@ -62,7 +62,7 @@ VifTeardown(
 
 // CALLBACKS
 
-extern VOID
+extern BOOLEAN
 VifReceiverQueuePacket(
     IN  PXENVIF_VIF_CONTEXT             Context,
     IN  ULONG                           Index,
-- 
2.25.0.windows.1




 


Rackspace

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