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

[PATCH xenvif 4/4] Add a Pause flag to the XENVIF_RECEIVER_QUEUE_PACKET callback parameters



From: Paul Durrant <pdurrant@xxxxxxxxxx>

The flag is used by the client driver to ask XENVIF to stop queueing packets
for a short period i.e. the current DPC invocation. Another DPC is scheduled
to process the remainder before any more packets are removed from the
descriptor ring (hence back-pressuring the network backend).

This patch involves bumping XENVIF_VIF_INTERFACE up to version 10. Code
is also added to set the Pause flag on behalf of older client drivers if
more than 1024 packets have been queued by a single DPC invocation.

This code is based on original patches [1] and [2] by Martin Harvey at Citrix.

[1] 
https://lists.xenproject.org/archives/html/win-pv-devel/2022-05/msg00043.html
[2] 
https://lists.xenproject.org/archives/html/win-pv-devel/2022-05/msg00042.html

Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
Cc: Martin Harvey <Martin.Harvey@xxxxxxxxxx>
Cc: Owen Smith <owen.smith@xxxxxxxxxx>

 include/revision.h      |   9 +-
 include/vif_interface.h |  80 ++++++++++++++++--
 src/xenvif/receiver.c   |  77 ++++++++++++-----
 src/xenvif/vif.c        | 181 ++++++++++++++++++++++++++++++++++++++--
 src/xenvif/vif.h        |   3 +-
 5 files changed, 311 insertions(+), 39 deletions(-)

diff --git a/include/revision.h b/include/revision.h
index 64e6e34ae14a..4085f0423edc 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -38,10 +38,11 @@
 // ST - XENBUS_STORE_INTERFACE
 // SU - XENBUS_SUSPEND_INTERFACE
 
-//                    REVISION   C   V   ST  SU
+//                    REVISION   C   V    ST  SU
 #define DEFINE_REVISION_TABLE                       \
-    DEFINE_REVISION(0x09000000,  1,  8,  2,  1),    \
-    DEFINE_REVISION(0x09000001,  2,  8,  2,  1),    \
-    DEFINE_REVISION(0x09000002,  2,  9,  2,  1)
+    DEFINE_REVISION(0x09000000,  1,  8,   2,  1),   \
+    DEFINE_REVISION(0x09000001,  2,  8,   2,  1),   \
+    DEFINE_REVISION(0x09000002,  2,  9,   2,  1),   \
+    DEFINE_REVISION(0x09000003,  2,  10,  2,  1)
 
 #endif  // _REVISION_H
diff --git a/include/vif_interface.h b/include/vif_interface.h
index c157c5ca798e..a600d35e8f23 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -388,7 +388,27 @@ typedef enum _XENVIF_VIF_CALLBACK_TYPE {
     XENVIF_MAC_STATE_CHANGE
 } XENVIF_VIF_CALLBACK_TYPE, *PXENVIF_VIF_CALLBACK_TYPE;
 
-/*! \typedef XENVIF_VIF_CALLBACK_PARAMETERS_V9
+union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 {
+    struct {
+        PVOID                                       Cookie;
+        PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion;
+    } TransmitterReturnPacket;
+    struct {
+        ULONG                           Index;
+        PMDL                            Mdl;
+        ULONG                           Offset;
+        ULONG                           Length;
+        XENVIF_PACKET_CHECKSUM_FLAGS    Flags;
+        USHORT                          MaximumSegmentSize;
+        USHORT                          TagControlInformation;
+        PXENVIF_PACKET_INFO             Info;
+        PXENVIF_PACKET_HASH             Hash;
+        BOOLEAN                         More;
+        PVOID                           Cookie;
+    } ReceiverQueuePacket;
+};
+
+/*! \typedef XENVIF_VIF_CALLBACK_PARAMETERS_V10
     \brief VIF interface version 9 parameters for provider to subscriber 
callback function
 
     \b XENVIF_TRANSMITTER_RETURN_PACKET:
@@ -407,11 +427,12 @@ typedef enum _XENVIF_VIF_CALLBACK_TYPE {
     \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
+    \param Pause A flag to request that no more packets be queued for a short 
period of time
 
     \b XENVIF_MAC_STATE_CHANGE:
     No additional arguments
 */
-union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 {
+union _XENVIF_VIF_CALLBACK_PARAMETERS_V10 {
     struct {
         PVOID                                       Cookie;
         PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO  Completion;
@@ -428,6 +449,7 @@ union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 {
         PXENVIF_PACKET_HASH             Hash;
         BOOLEAN                         More;
         PVOID                           Cookie;
+        BOOLEAN                         Pause;
     } ReceiverQueuePacket;
 };
 
@@ -458,7 +480,14 @@ typedef VOID
     ...
     );
 
-typedef union _XENVIF_VIF_CALLBACK_PARAMETERS_V9 
XENVIF_VIF_CALLBACK_PARAMETERS, *PXENVIF_VIF_CALLBACK_PARAMETERS;
+typedef VOID
+(*XENVIF_VIF_CALLBACK_V9)(
+    IN  PVOID                                       Argument OPTIONAL,
+    IN  XENVIF_VIF_CALLBACK_TYPE                    Type,
+    IN  union _XENVIF_VIF_CALLBACK_PARAMETERS_V9   *Parameters
+    );
+
+typedef union _XENVIF_VIF_CALLBACK_PARAMETERS_V10 
XENVIF_VIF_CALLBACK_PARAMETERS, *PXENVIF_VIF_CALLBACK_PARAMETERS;
 
 /*! \typedef XENVIF_VIF_CALLBACK
     \brief Provider to subscriber callback function
@@ -481,6 +510,13 @@ typedef NTSTATUS
     IN  PVOID                   Argument OPTIONAL
     );
 
+typedef NTSTATUS
+(*XENVIF_VIF_ENABLE_V9)(
+    IN  PINTERFACE              Interface,
+    IN  XENVIF_VIF_CALLBACK_V9  Callback,
+    IN  PVOID                   Argument OPTIONAL
+    );
+
 /*! \typedef XENVIF_VIF_ENABLE
     \brief Enable the VIF interface
 
@@ -891,6 +927,40 @@ struct _XENVIF_VIF_INTERFACE_V8 {
     \ingroup interfaces
 */
 struct _XENVIF_VIF_INTERFACE_V9 {
+    INTERFACE                                       Interface;
+    XENVIF_VIF_ACQUIRE                              Acquire;
+    XENVIF_VIF_RELEASE                              Release;
+    XENVIF_VIF_ENABLE_V9                            EnableVersion9;
+    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             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_V10
+    \brief VIF interface version 10
+    \ingroup interfaces
+*/
+struct _XENVIF_VIF_INTERFACE_V10 {
     INTERFACE                                       Interface;
     XENVIF_VIF_ACQUIRE                              Acquire;
     XENVIF_VIF_RELEASE                              Release;
@@ -920,7 +990,7 @@ struct _XENVIF_VIF_INTERFACE_V9 {
     XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
 };
 
-typedef struct _XENVIF_VIF_INTERFACE_V9 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
+typedef struct _XENVIF_VIF_INTERFACE_V10 XENVIF_VIF_INTERFACE, 
*PXENVIF_VIF_INTERFACE;
 
 /*! \def XENVIF_VIF
     \brief Macro at assist in method invocation
@@ -931,6 +1001,6 @@ typedef struct _XENVIF_VIF_INTERFACE_V9 
XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTER
 #endif  // _WINDLL
 
 #define XENVIF_VIF_INTERFACE_VERSION_MIN    8
-#define XENVIF_VIF_INTERFACE_VERSION_MAX    9
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    10
 
 #endif  // _XENVIF_INTERFACE_H
diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index d4703b9bd322..21451331d330 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -109,6 +109,8 @@ typedef struct _XENVIF_RECEIVER_RING {
     PROCESSOR_NUMBER            TargetProcessor;
     LIST_ENTRY                  PacketComplete;
     XENVIF_RECEIVER_HASH        Hash;
+    BOOLEAN                     Paused;
+    BOOLEAN                     Flush;
 } XENVIF_RECEIVER_RING, *PXENVIF_RECEIVER_RING;
 
 typedef struct _XENVIF_RECEIVER_PACKET {
@@ -1338,6 +1340,7 @@ __ReceiverRingSwizzle(
     PXENVIF_VIF_CONTEXT         Context;
     LIST_ENTRY                  List;
     PLIST_ENTRY                 ListEntry;
+    BOOLEAN                     Pause;
 
     Receiver = Ring->Receiver;
     Frontend = Receiver->Frontend;
@@ -1345,36 +1348,42 @@ __ReceiverRingSwizzle(
 
     InitializeListHead(&List);
 
-    ListEntry = InterlockedExchangePointer(&Ring->PacketQueue, NULL);
+    KeMemoryBarrier();
 
-    // 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.
+    // Only process the PacketQueue if the ring is not paused or it is being 
flushed
+    if (!Ring->Paused || Ring->Flush) {
+        ListEntry = InterlockedExchangePointer(&Ring->PacketQueue, NULL);
 
-    while (ListEntry != NULL) {
-        PLIST_ENTRY NextEntry;
+        // 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.
 
-        NextEntry = ListEntry->Blink;
-        ListEntry->Flink = ListEntry->Blink = ListEntry;
+        while (ListEntry != NULL) {
+            PLIST_ENTRY NextEntry;
 
-        InsertHeadList(&List, ListEntry);
+            NextEntry = ListEntry->Blink;
+            ListEntry->Flink = ListEntry->Blink = ListEntry;
 
-        ListEntry = NextEntry;
-    }
+            InsertHeadList(&List, ListEntry);
 
-    while (!IsListEmpty(&List)) {
-        PXENVIF_RECEIVER_PACKET Packet;
+            ListEntry = NextEntry;
+        }
 
-        ListEntry = RemoveHeadList(&List);
-        ASSERT3P(ListEntry, !=, &List);
+        while (!IsListEmpty(&List)) {
+            PXENVIF_RECEIVER_PACKET Packet;
 
-        RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+            ListEntry = RemoveHeadList(&List);
+            ASSERT3P(ListEntry, !=, &List);
 
-        Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, 
ListEntry);
-        ReceiverRingProcessPacket(Ring, Packet);
+            RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+
+            Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, 
ListEntry);
+            ReceiverRingProcessPacket(Ring, Packet);
+        }
     }
 
-    while (!IsListEmpty(&Ring->PacketComplete)) {
+    Pause = FALSE;
+    while (!IsListEmpty(&Ring->PacketComplete) && !Pause) {
         PXENVIF_RECEIVER_PACKET Packet;
         PXENVIF_PACKET_INFO     Info;
         PUCHAR                  BaseVa;
@@ -1538,7 +1547,27 @@ __ReceiverRingSwizzle(
                                &Packet->Info,
                                &Packet->Hash,
                                !IsListEmpty(&Ring->PacketComplete) ? TRUE : 
FALSE,
-                               Packet);
+                               Packet,
+                               &Pause);
+
+        // If we are flushing then we can't pause
+        if (Ring->Flush)
+            Pause = FALSE;
+    }
+
+    if (Pause) {
+        Ring->Paused = TRUE;
+
+        if (KeInsertQueueDpc(&Ring->QueueDpc, NULL, NULL))
+            Ring->QueueDpcs++;
+    } else {
+        BOOLEAN Paused = Ring->Paused;
+
+        Ring->Paused = FALSE;
+
+        // PollDpc is cleared before Flush is set
+        if (Paused && !Ring->Flush && KeInsertQueueDpc(&Ring->PollDpc, NULL, 
NULL))
+            Ring->PollDpcs++;
     }
 }
 
@@ -1990,7 +2019,7 @@ ReceiverRingPoll(
 
     Count = 0;
 
-    if (!Ring->Enabled)
+    if (!Ring->Enabled || Ring->Paused)
         goto done;
 
     for (;;) {
@@ -2965,7 +2994,13 @@ __ReceiverRingTeardown(
 
     RtlZeroMemory(&Ring->TargetProcessor, sizeof (PROCESSOR_NUMBER));
 
+    Ring->Flush = TRUE;
+    KeMemoryBarrier();
+
+    KeInsertQueueDpc(&Ring->QueueDpc, NULL, NULL);
     KeFlushQueuedDpcs();
+    Ring->Flush = FALSE;
+
     RtlZeroMemory(&Ring->QueueDpc, sizeof (KDPC));
 
     ThreadAlert(Ring->WatchdogThread);
diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c
index 102f24d12888..3e02dbc8dcd4 100644
--- a/src/xenvif/vif.c
+++ b/src/xenvif/vif.c
@@ -55,6 +55,9 @@ struct _XENVIF_VIF_CONTEXT {
     PVOID                       Argument;
     XENVIF_VIF_CALLBACK_V8      CallbackVersion8;
     PVOID                       ArgumentVersion8;
+    XENVIF_VIF_CALLBACK_V9      CallbackVersion9;
+    PVOID                       ArgumentVersion9;
+    LONG                        Queued;
     PXENVIF_THREAD              MacThread;
     KEVENT                      MacEvent;
     XENBUS_SUSPEND_INTERFACE    SuspendInterface;
@@ -239,14 +242,14 @@ fail1:
 
 static VOID
 VifCallbackVersion8(
-    IN  PVOID                           _Argument OPTIONAL,
-    IN  XENVIF_VIF_CALLBACK_TYPE        Type,
-    IN  PXENVIF_VIF_CALLBACK_PARAMETERS Parameters
+    IN  PVOID                                       _Argument OPTIONAL,
+    IN  XENVIF_VIF_CALLBACK_TYPE                    Type,
+    IN  union _XENVIF_VIF_CALLBACK_PARAMETERS_V9   *Parameters
     )
 {
-    PXENVIF_VIF_CONTEXT                 Context = _Argument;
-    XENVIF_VIF_CALLBACK_V8              Callback = Context->CallbackVersion8;
-    PVOID                               Argument = Context->ArgumentVersion8;
+    PXENVIF_VIF_CONTEXT                             Context = _Argument;
+    XENVIF_VIF_CALLBACK_V8                          Callback = 
Context->CallbackVersion8;
+    PVOID                                           Argument = 
Context->ArgumentVersion8;
 
     switch (Type) {
     case XENVIF_TRANSMITTER_RETURN_PACKET: {
@@ -297,6 +300,113 @@ VifCallbackVersion8(
     }
 }
 
+static VOID
+VifCallbackVersion9(
+    IN  PVOID                                       _Argument OPTIONAL,
+    IN  XENVIF_VIF_CALLBACK_TYPE                    Type,
+    IN  PXENVIF_VIF_CALLBACK_PARAMETERS             Parameters
+    )
+{
+#define XENVIF_RECEIVER_QUEUE_MAX 1024 // Chosen to match IN_NDIS_MAX in XENNET
+
+    PXENVIF_VIF_CONTEXT                             Context = _Argument;
+    XENVIF_VIF_CALLBACK_V9                          Callback = 
Context->CallbackVersion9;
+    PVOID                                           Argument = 
Context->ArgumentVersion9;
+    union _XENVIF_VIF_CALLBACK_PARAMETERS_V9        ParametersVersion9;
+
+    switch (Type) {
+    case XENVIF_TRANSMITTER_RETURN_PACKET:
+        ParametersVersion9.TransmitterReturnPacket.Cookie = 
Parameters->TransmitterReturnPacket.Cookie;
+        ParametersVersion9.TransmitterReturnPacket.Completion = 
Parameters->TransmitterReturnPacket.Completion;
+        break;
+
+    case XENVIF_RECEIVER_QUEUE_PACKET:
+        ParametersVersion9.ReceiverQueuePacket.Index = 
Parameters->ReceiverQueuePacket.Index;
+        ParametersVersion9.ReceiverQueuePacket.Mdl = 
Parameters->ReceiverQueuePacket.Mdl;
+        ParametersVersion9.ReceiverQueuePacket.Offset = 
Parameters->ReceiverQueuePacket.Offset;
+        ParametersVersion9.ReceiverQueuePacket.Length = 
Parameters->ReceiverQueuePacket.Length;
+        ParametersVersion9.ReceiverQueuePacket.Flags = 
Parameters->ReceiverQueuePacket.Flags;
+        ParametersVersion9.ReceiverQueuePacket.MaximumSegmentSize = 
Parameters->ReceiverQueuePacket.MaximumSegmentSize;
+        ParametersVersion9.ReceiverQueuePacket.TagControlInformation = 
Parameters->ReceiverQueuePacket.TagControlInformation;
+        ParametersVersion9.ReceiverQueuePacket.Info = 
Parameters->ReceiverQueuePacket.Info;
+        ParametersVersion9.ReceiverQueuePacket.Hash = 
Parameters->ReceiverQueuePacket.Hash;
+        ParametersVersion9.ReceiverQueuePacket.More = 
Parameters->ReceiverQueuePacket.More;
+        ParametersVersion9.ReceiverQueuePacket.Cookie = 
Parameters->ReceiverQueuePacket.Cookie;
+        break;
+
+    case XENVIF_MAC_STATE_CHANGE:
+        // No parameters to translate
+        break;
+
+    default:
+        ASSERT(FALSE);
+        break;
+    }
+
+    Callback(Argument, Type, &ParametersVersion9);
+
+    switch (Type) {
+    case XENVIF_TRANSMITTER_RETURN_PACKET:
+        break;
+
+    case XENVIF_RECEIVER_QUEUE_PACKET: {
+        LONG Queued;
+
+        Queued = (Parameters->ReceiverQueuePacket.More) ?
+            InterlockedIncrement(&Context->Queued) :
+            InterlockedExchange(&Context->Queued, 0);
+
+        //
+        // Once the limit is hit XENNET will have started indicating 'low 
resources' to NDIS so we
+        // should pause any further attempts to queue received packets.
+        //
+        if (Queued > XENVIF_RECEIVER_QUEUE_MAX) {
+            Parameters->ReceiverQueuePacket.Pause = TRUE;
+            (VOID) InterlockedExchange(&Context->Queued, 0);
+        } else {
+            Parameters->ReceiverQueuePacket.Pause = FALSE;
+        }
+        break;
+    }
+    case XENVIF_MAC_STATE_CHANGE:
+        // No parameters to translate
+        break;
+
+    default:
+        ASSERT(FALSE);
+        break;
+    }
+
+#undef XENVIF_RECEIVER_QUEUE_MAX
+}
+
+static NTSTATUS
+VifEnableVersion9(
+    IN  PINTERFACE                  Interface,
+    IN  XENVIF_VIF_CALLBACK_V9      Callback,
+    IN  PVOID                       Argument
+    )
+{
+    PXENVIF_VIF_CONTEXT             Context = Interface->Context;
+    KIRQL                           Irql;
+    NTSTATUS                        status;
+
+    Trace("====>\n");
+
+    AcquireMrswLockExclusive(&Context->Lock, &Irql);
+
+    Context->CallbackVersion9 = Callback;
+    Context->ArgumentVersion9 = Argument;
+
+    ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
+
+    status = VifEnable(Interface, VifCallbackVersion9, Context);
+
+    Trace("<====\n");
+
+    return status;
+}
+
 static NTSTATUS
 VifEnableVersion8(
     IN  PINTERFACE                  Interface,
@@ -317,7 +427,7 @@ VifEnableVersion8(
 
     ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
 
-    status = VifEnable(Interface, VifCallbackVersion8, Context);
+    status = VifEnableVersion9(Interface, VifCallbackVersion8, Context);
 
     Trace("<====\n");
 
@@ -378,6 +488,9 @@ VifDisable(
     Context->ArgumentVersion8 = NULL;
     Context->CallbackVersion8 = NULL;
 
+    Context->ArgumentVersion9 = NULL;
+    Context->CallbackVersion9 = NULL;
+
     ReleaseMrswLockShared(&Context->Lock);
 
 done:
@@ -914,6 +1027,36 @@ static struct _XENVIF_VIF_INTERFACE_V9 
VifInterfaceVersion9 = {
     { sizeof (struct _XENVIF_VIF_INTERFACE_V9), 9, NULL, NULL, NULL },
     VifAcquire,
     VifRelease,
+    VifEnableVersion9,
+    VifDisable,
+    VifQueryStatistic,
+    VifQueryRingCount,
+    VifUpdateHashMapping,
+    VifReceiverReturnPacket,
+    VifReceiverSetOffloadOptions,
+    VifReceiverSetBackfillSize,
+    VifReceiverQueryRingSize,
+    VifReceiverSetHashAlgorithm,
+    VifReceiverQueryHashCapabilities,
+    VifReceiverUpdateHashParameters,
+    VifTransmitterQueuePacket,
+    VifTransmitterQueryOffloadOptions,
+    VifTransmitterQueryLargePacketSize,
+    VifTransmitterQueryRingSize,
+    VifMacQueryState,
+    VifMacQueryMaximumFrameSize,
+    VifMacQueryPermanentAddress,
+    VifMacQueryCurrentAddress,
+    VifMacQueryMulticastAddresses,
+    VifMacSetMulticastAddresses,
+    VifMacSetFilterLevel,
+    VifMacQueryFilterLevel
+};
+
+static struct _XENVIF_VIF_INTERFACE_V10 VifInterfaceVersion10 = {
+    { sizeof (struct _XENVIF_VIF_INTERFACE_V10), 10, NULL, NULL, NULL },
+    VifAcquire,
+    VifRelease,
     VifEnable,
     VifDisable,
     VifQueryStatistic,
@@ -1038,6 +1181,23 @@ VifGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 10: {
+        struct _XENVIF_VIF_INTERFACE_V10 *VifInterface;
+
+        VifInterface = (struct _XENVIF_VIF_INTERFACE_V10 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENVIF_VIF_INTERFACE_V10))
+            break;
+
+        *VifInterface = VifInterfaceVersion10;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
@@ -1053,6 +1213,8 @@ VifTeardown(
 {
     Trace("====>\n");
 
+    Context->Queued = 0;
+
     Context->Pdo = NULL;
     Context->Version = 0;
 
@@ -1086,7 +1248,8 @@ VifReceiverQueuePacket(
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
     IN  BOOLEAN                         More,
-    IN  PVOID                           Cookie
+    IN  PVOID                           Cookie,
+    OUT PBOOLEAN                        Pause
     )
 {
     KIRQL                               Irql;
@@ -1110,6 +1273,8 @@ VifReceiverQueuePacket(
 
     Context->Callback(Context->Argument, XENVIF_RECEIVER_QUEUE_PACKET, 
&Parameters);
 
+    *Pause = Parameters.ReceiverQueuePacket.Pause;
+
     KeLowerIrql(Irql);
 }
 
diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h
index b83a767751ed..76e9d07259a8 100644
--- a/src/xenvif/vif.h
+++ b/src/xenvif/vif.h
@@ -75,7 +75,8 @@ VifReceiverQueuePacket(
     IN  PXENVIF_PACKET_INFO             Info,
     IN  PXENVIF_PACKET_HASH             Hash,
     IN  BOOLEAN                         More,
-    IN  PVOID                           Cookie
+    IN  PVOID                           Cookie,
+    OUT PBOOLEAN                        Pause
     );
 
 extern VOID
-- 
2.17.1




 


Rackspace

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