[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |