]> xenbits.xensource.com Git - people/pauldu/xenvif.git/commitdiff
Add batching support
authorPaul Durrant <paul.durrant@citrix.com>
Mon, 15 Aug 2016 13:06:30 +0000 (14:06 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Wed, 17 Aug 2016 10:55:27 +0000 (11:55 +0100)
If a NET_BUFFER_LIST comprising multiple NET_BUFFERs is handled by XENNET
then this will result in multiple calls to VifTransmitterQueuePacket().
There is no need to attempt to process the transmit queue after every single
one of these calls, it suffices to just do it after the last of them. Hence
this patch adds an extra argument such that XENNET can notify XENVIF when
the last call of a batch is made.

Similarly on the receive side, it is useful notify XENNET when the last of
a batch of calls to the XENVIF_RECEIVER_QUEUE_PACKET callback is made, since
XENNET can then batch received packet indications to the NDIS stack.

These changes are made in XENVIF_VIF_INTERACE version 7.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
include/revision.h
include/vif_interface.h
src/xenvif/receiver.c
src/xenvif/transmitter.c
src/xenvif/transmitter.h
src/xenvif/vif.c
src/xenvif/vif.h

index 14b7b1559a4998c323d41adfdb34dc0c005a0525..4adf4e9a9a2a0ccfd6e4ca81eecbb72c4a5e2530 100644 (file)
@@ -45,7 +45,8 @@
     DEFINE_REVISION(0x08000004,  1,  3,  2,  1),    \
     DEFINE_REVISION(0x08000006,  1,  4,  2,  1),    \
     DEFINE_REVISION(0x08000009,  1,  5,  2,  1),    \
-    DEFINE_REVISION(0x0800000B,  1,  6,  2,  1)
+    DEFINE_REVISION(0x0800000B,  1,  6,  2,  1),    \
+    DEFINE_REVISION(0x0800000C,  1,  7,  2,  1)
 
 // Revision 0x08000005, 0x08000007, 0x08000008 and 0x0800000A are already
 // in use in the staging-8.1 branch.
index 853554df659cf4a14d2320f40a8f49446b9a2351..4a9598917f4fb6f28f9720af2d419f8cf44e0b19 100644 (file)
@@ -391,6 +391,7 @@ typedef VOID
     \param TagControlInformation The VLAN TCI (used only if OffloadOptions.OffloadTagManipulation is set)
     \param Info Header information for the packet
     \param Hash Hash information for the packet
+    \param More A flag to indicate whether more packets will be queued for the same CPU
     \param Cookie Cookie that should be passed to XENVIF_RECEIVER_RETURN_PACKET method
 
     \b XENVIF_MAC_STATE_CHANGE:
@@ -527,6 +528,19 @@ typedef VOID
     IN  PVOID                       Cookie
     );
 
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5)(
+    IN  PINTERFACE                  Interface,
+    IN  PMDL                        Mdl,
+    IN  ULONG                       Offset,
+    IN  ULONG                       Length,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions,
+    IN  USHORT                      MaximumSegmentSize,
+    IN  USHORT                      TagControlInformation,
+    IN  PXENVIF_PACKET_HASH         Hash,
+    IN  PVOID                       Cookie
+    );
+
 /*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKET
     \brief Queue a packet at the provider's transmit side
 
@@ -538,6 +552,7 @@ typedef VOID
     \param MaximumSegmentSize The TCP MSS (used only if OffloadOptions.OffloadIpVersion[4|6]LargePacket is set)
     \param TagControlInformation The VLAN TCI (used only if OffloadOptions.OffloadTagManipulation is set)
     \param Hash Hash information for the packet
+    \param More A flag to indicate whether there will more packets queued with the same value of Hash
     \param Cookie A cookie specified by the caller that will be passed to the XENVIF_TRANSMITTER_RETURN_PACKET callback
 */
 typedef NTSTATUS
@@ -550,6 +565,7 @@ typedef NTSTATUS
     IN  USHORT                      MaximumSegmentSize,
     IN  USHORT                      TagControlInformation,
     IN  PXENVIF_PACKET_HASH         Hash,
+    IN  BOOLEAN                     More,
     IN  PVOID                       Cookie
     );
 
@@ -908,7 +924,7 @@ struct _XENVIF_VIF_INTERFACE_V5 {
     XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
     XENVIF_VIF_RECEIVER_SET_BACKFILL_SIZE           ReceiverSetBackfillSize;
     XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
-    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET             TransmitterQueuePacket;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKET_V5          TransmitterQueuePacket;
     XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    TransmitterQueryOffloadOptions;
     XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  TransmitterQueryLargePacketSize;
     XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
@@ -927,6 +943,40 @@ struct _XENVIF_VIF_INTERFACE_V5 {
     \ingroup interfaces
 */
 struct _XENVIF_VIF_INTERFACE_V6 {
+    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_V5          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;
+};
+
+/*! \struct _XENVIF_VIF_INTERFACE_V7
+    \brief VIF interface version 7
+    \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V7 {
     INTERFACE                                       Interface;
     XENVIF_VIF_ACQUIRE                              Acquire;
     XENVIF_VIF_RELEASE                              Release;
@@ -956,7 +1006,7 @@ struct _XENVIF_VIF_INTERFACE_V6 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V6 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V7 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -967,6 +1017,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V6 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    2
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    6
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    7
 
 #endif  // _XENVIF_INTERFACE_H
index a33f8ced1e45cc16602f0ca04fc2d8b292caa9eb..844e243f17dc5b2c77ca186363193826544ad324 100644 (file)
@@ -1444,6 +1444,7 @@ __ReceiverRingReleaseLock(
                                Packet->TagControlInformation,
                                &Packet->Info,
                                &Packet->Hash,
+                               !IsListEmpty(&List),
                                Packet);
     }
 
index 084ca76ca861ec2786472517ff6aaca97b3ac2d9..88add2f256bad1189860b624efb07b8df33b2465 100644 (file)
@@ -3983,7 +3983,8 @@ __TransmitterRingTeardown(
 static FORCEINLINE VOID
 __TransmitterRingQueuePacket(
     IN  PXENVIF_TRANSMITTER_RING    Ring,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet,
+    IN  BOOLEAN                     More
     )
 {
     PLIST_ENTRY                     ListEntry;
@@ -4008,6 +4009,9 @@ __TransmitterRingQueuePacket(
     // grab it then that's ok because whichever thread is holding it will have to call
     // __TransmitterRingReleaseLock() and will therefore drain the atomic packet list.
 
+    if (More)
+        return;
+
     if (__TransmitterRingTryAcquireLock(Ring))
         __TransmitterRingReleaseLock(Ring);
 }
@@ -4895,6 +4899,7 @@ TransmitterQueuePacket(
     IN  USHORT                      MaximumSegmentSize,
     IN  USHORT                      TagControlInformation,
     IN  PXENVIF_PACKET_HASH         Hash,
+    IN  BOOLEAN                     More,
     IN  PVOID                       Cookie
     )
 {
@@ -4939,9 +4944,14 @@ TransmitterQueuePacket(
     switch (Hash->Algorithm) {
     case XENVIF_PACKET_HASH_ALGORITHM_NONE:
         Value = __TransmitterHashPacket(Packet);
+        More = FALSE;
         break;
 
     case XENVIF_PACKET_HASH_ALGORITHM_UNSPECIFIED:
+        Value = Hash->Value;
+        More = FALSE;
+        break;
+
     case XENVIF_PACKET_HASH_ALGORITHM_TOEPLITZ:
         Value = Hash->Value;
         break;
@@ -4955,7 +4965,7 @@ TransmitterQueuePacket(
     Index = FrontendGetQueue(Frontend, Value);
     Ring = Transmitter->Ring[Index];
 
-    __TransmitterRingQueuePacket(Ring, Packet);
+    __TransmitterRingQueuePacket(Ring, Packet, More);
 
     return STATUS_SUCCESS;
 
index 5e74667b5a7a0cf48c232b580b3df130fb74281d..d44f77ea7151e6d63045e9afd492428d25db04e3 100644 (file)
@@ -125,6 +125,7 @@ TransmitterQueuePacket(
     IN  USHORT                      MaximumSegmentSize,
     IN  USHORT                      TagControlInformation,
     IN  PXENVIF_PACKET_HASH         Hash,
+    IN  BOOLEAN                     More,
     IN  PVOID                       Cookie
     );
 
index 5501e25464b5f02027de5aa3be3b27c2566cdcfe..cb28aa55217ad690d5f5439638a0d72c3d3b63b7 100644 (file)
@@ -535,6 +535,7 @@ VifTransmitterQueuePacketsVersion2(
                                         PacketVersion2->Send.MaximumSegmentSize,
                                         PacketVersion2->Send.TagControlInformation,
                                         &Hash,
+                                        FALSE,
                                         PacketVersion2);
         if (!NT_SUCCESS(status))
             InsertTailList(&Reject, &PacketVersion2->ListEntry);
@@ -585,6 +586,7 @@ VifTransmitterQueuePacketVersion4(
                                     MaximumSegmentSize,
                                     TagControlInformation,
                                     Hash,
+                                    FALSE,
                                     Cookie);
 
 done:
@@ -603,6 +605,45 @@ done:
     }
 }
 
+static NTSTATUS
+VifTransmitterQueuePacketVersion5(
+    IN  PINTERFACE                  Interface,
+    IN  PMDL                        Mdl,
+    IN  ULONG                       Offset,
+    IN  ULONG                       Length,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions,
+    IN  USHORT                      MaximumSegmentSize,
+    IN  USHORT                      TagControlInformation,
+    IN  PXENVIF_PACKET_HASH         Hash,
+    IN  PVOID                       Cookie
+    )
+{
+    PXENVIF_VIF_CONTEXT             Context = Interface->Context;
+    NTSTATUS                        status;
+
+    AcquireMrswLockShared(&Context->Lock);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (Context->Enabled == FALSE)
+        goto done;
+
+    status = TransmitterQueuePacket(FrontendGetTransmitter(Context->Frontend),
+                                    Mdl,
+                                    Offset,
+                                    Length,
+                                    OffloadOptions,
+                                    MaximumSegmentSize,
+                                    TagControlInformation,
+                                    Hash,
+                                    FALSE,
+                                    Cookie);
+
+done:
+    ReleaseMrswLockShared(&Context->Lock);
+
+    return status;
+}
+
 static NTSTATUS
 VifTransmitterQueuePacket(
     IN  PINTERFACE                  Interface,
@@ -613,6 +654,7 @@ VifTransmitterQueuePacket(
     IN  USHORT                      MaximumSegmentSize,
     IN  USHORT                      TagControlInformation,
     IN  PXENVIF_PACKET_HASH         Hash,
+    IN  BOOLEAN                     More,
     IN  PVOID                       Cookie
     )
 {
@@ -633,6 +675,7 @@ VifTransmitterQueuePacket(
                                     MaximumSegmentSize,
                                     TagControlInformation,
                                     Hash,
+                                    More,
                                     Cookie);
 
 done:
@@ -1107,7 +1150,7 @@ static struct _XENVIF_VIF_INTERFACE_V5 VifInterfaceVersion5 = {
     VifReceiverSetOffloadOptions,
     VifReceiverSetBackfillSize,
     VifReceiverQueryRingSize,
-    VifTransmitterQueuePacket,
+    VifTransmitterQueuePacketVersion5,
     VifTransmitterQueryOffloadOptions,
     VifTransmitterQueryLargePacketSize,
     VifTransmitterQueryRingSize,
@@ -1137,6 +1180,36 @@ static struct _XENVIF_VIF_INTERFACE_V6 VifInterfaceVersion6 = {
     VifReceiverSetHashAlgorithm,
     VifReceiverQueryHashCapabilities,
     VifReceiverUpdateHashParameters,
+    VifTransmitterQueuePacketVersion5,
+    VifTransmitterQueryOffloadOptions,
+    VifTransmitterQueryLargePacketSize,
+    VifTransmitterQueryRingSize,
+    VifMacQueryState,
+    VifMacQueryMaximumFrameSize,
+    VifMacQueryPermanentAddress,
+    VifMacQueryCurrentAddress,
+    VifMacQueryMulticastAddresses,
+    VifMacSetMulticastAddresses,
+    VifMacSetFilterLevel,
+    VifMacQueryFilterLevel
+};
+
+static struct _XENVIF_VIF_INTERFACE_V7 VifInterfaceVersion7 = {
+    { sizeof (struct _XENVIF_VIF_INTERFACE_V7), 7, NULL, NULL, NULL },
+    VifAcquire,
+    VifRelease,
+    VifEnable,
+    VifDisable,
+    VifQueryStatistic,
+    VifQueryRingCount,
+    VifUpdateHashMapping,
+    VifReceiverReturnPacket,
+    VifReceiverSetOffloadOptions,
+    VifReceiverSetBackfillSize,
+    VifReceiverQueryRingSize,
+    VifReceiverSetHashAlgorithm,
+    VifReceiverQueryHashCapabilities,
+    VifReceiverUpdateHashParameters,
     VifTransmitterQueuePacket,
     VifTransmitterQueryOffloadOptions,
     VifTransmitterQueryLargePacketSize,
@@ -1300,6 +1373,23 @@ VifGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 7: {
+        struct _XENVIF_VIF_INTERFACE_V7 *VifInterface;
+
+        VifInterface = (struct _XENVIF_VIF_INTERFACE_V7 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENVIF_VIF_INTERFACE_V7))
+            break;
+
+        *VifInterface = VifInterfaceVersion7;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
@@ -1346,6 +1436,7 @@ __VifReceiverQueuePacketVersion1(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     )
 {
@@ -1355,6 +1446,7 @@ __VifReceiverQueuePacketVersion1(
     NTSTATUS                            status;
 
     UNREFERENCED_PARAMETER(Hash);
+    UNREFERENCED_PARAMETER(More);
 
     InfoVersion1 = __VifAllocate(sizeof (struct _XENVIF_PACKET_INFO_V1));
 
@@ -1420,11 +1512,70 @@ __VifReceiverQueuePacketVersion4(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     )
 {
     UNREFERENCED_PARAMETER(Hash);
+    UNREFERENCED_PARAMETER(More);
+
+    Context->Callback(Context->Argument,
+                      XENVIF_RECEIVER_QUEUE_PACKET,
+                      Mdl,
+                      Offset,
+                      Length,
+                      Flags,
+                      MaximumSegmentSize,
+                      TagControlInformation,
+                      Info,
+                      Cookie);
+}
+
+static FORCEINLINE VOID
+__VifReceiverQueuePacketVersion6(
+    IN  PXENVIF_VIF_CONTEXT             Context,
+    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
+    )
+{
+    UNREFERENCED_PARAMETER(More);
+
+    Context->Callback(Context->Argument,
+                      XENVIF_RECEIVER_QUEUE_PACKET,
+                      Mdl,
+                      Offset,
+                      Length,
+                      Flags,
+                      MaximumSegmentSize,
+                      TagControlInformation,
+                      Info,
+                      Hash,
+                      Cookie);
+}
 
+static FORCEINLINE VOID
+__VifReceiverQueuePacket(
+    IN  PXENVIF_VIF_CONTEXT             Context,
+    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
+    )
+{
     Context->Callback(Context->Argument,
                       XENVIF_RECEIVER_QUEUE_PACKET,
                       Mdl,
@@ -1434,6 +1585,8 @@ __VifReceiverQueuePacketVersion4(
                       MaximumSegmentSize,
                       TagControlInformation,
                       Info,
+                      Hash,
+                      More,
                       Cookie);
 }
 
@@ -1448,6 +1601,7 @@ VifReceiverQueuePacket(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     )
 {
@@ -1463,6 +1617,7 @@ VifReceiverQueuePacket(
                                          TagControlInformation,
                                          Info,
                                          Hash,
+                                         More,
                                          Cookie);
         break;
 
@@ -1477,21 +1632,36 @@ VifReceiverQueuePacket(
                                          TagControlInformation,
                                          Info,
                                          Hash,
+                                         More,
                                          Cookie);
         break;
 
     case 6:
-        Context->Callback(Context->Argument,
-                          XENVIF_RECEIVER_QUEUE_PACKET,
-                          Mdl,
-                          Offset,
-                          Length,
-                          Flags,
-                          MaximumSegmentSize,
-                          TagControlInformation,
-                          Info,
-                          Hash,
-                          Cookie);
+        __VifReceiverQueuePacketVersion6(Context,
+                                         Mdl,
+                                         Offset,
+                                         Length,
+                                         Flags,
+                                         MaximumSegmentSize,
+                                         TagControlInformation,
+                                         Info,
+                                         Hash,
+                                         More,
+                                         Cookie);
+        break;
+
+    case 7:
+        __VifReceiverQueuePacket(Context,
+                                 Mdl,
+                                 Offset,
+                                 Length,
+                                 Flags,
+                                 MaximumSegmentSize,
+                                 TagControlInformation,
+                                 Info,
+                                 Hash,
+                                 More,
+                                 Cookie);
         break;
 
     default:
@@ -1541,6 +1711,7 @@ VifTransmitterReturnPacket(
     case 4:
     case 5:
     case 6:
+    case 7:
         Context->Callback(Context->Argument,
                           XENVIF_TRANSMITTER_RETURN_PACKET,
                           Cookie,
index 6894ca290c0ffd642b2bae4da448be32b8ec5167..025871dfd117ef9ea2e7a137edf956db23e297b3 100644 (file)
@@ -79,6 +79,7 @@ VifReceiverQueuePacket(
     IN  USHORT                          TagControlInformation,
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
+    IN  BOOLEAN                         More,
     IN  PVOID                           Cookie
     );