[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] Rate limit per DPC using both xenvif and xennet.
Further development of rate limiting code, whereby both xenvif and xennet co-operate across the VIF interface to decide how many packets to push up the stack. This allows for the situation where NDIS could provide information at upstream push time about how many more packets it is prepared to accept in this DPC. Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx> --- include/revision.h | 3 +- include/vif_interface.h | 103 ++++++++++++++++++-- src/xenvif/receiver.c | 15 +-- src/xenvif/vif.c | 209 ++++++++++++++++++++++++++++++++++------ src/xenvif/vif.h | 2 +- 5 files changed, 285 insertions(+), 47 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..7056783 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -408,7 +408,7 @@ typedef VOID IN PINTERFACE Interface ); -/*! \typedef XENVIF_VIF_CALLBACK +/*! \typedef XENVIF_VIF_CALLBACK_V6 \brief Provider to subscriber callback function \param Argument An optional context argument passed to the callback @@ -436,13 +436,72 @@ typedef VOID No additional arguments */ typedef VOID -(*XENVIF_VIF_CALLBACK)( +(*XENVIF_VIF_CALLBACK_V6)( IN PVOID Argument OPTIONAL, IN XENVIF_VIF_CALLBACK_TYPE Type, ... ); -/*! \typedef XENVIF_VIF_ENABLE +/*! \typedef XENVIF_VIF_ENABLE_V6 + \brief Enable the VIF interface + + All packets queued for transmit will be rejected and no packets will + be queued for receive until this method completes. + + \param Interface The interface header + \param Callback The subscriber's callback function + \param Argument An optional context argument passed to the callback +*/ +typedef NTSTATUS +(*XENVIF_VIF_ENABLE_V6)( + IN PINTERFACE Interface, + IN XENVIF_VIF_CALLBACK_V6 Callback, + IN PVOID Argument OPTIONAL + ); + + +typedef union _XENVIF_VIF_CALLBACK_PARAMS { + struct _XENVIF_VIF_CALLBACK_RETURN_PACKET_PARAMS { + PVOID Cookie; + PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion; + } ReturnPacketParams; + struct _XENVIF_VIF_CALLBACK_QUEUE_PACKET_PARAMS { + 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; + PBOOLEAN NdisFinished; + } QueuePacketParams; + /* + struct _XENVIF_VIF_CALLBACK_STATE_CHANGE_PARAMS { + No parameters here + } StateChangeParams; + */ +} XENVIF_VIF_CALLBACK_PARAMS, *PXENVIF_VIF_CALLBACK_PARAMS; + +/*! \typedef XENVIF_VIF_CALLBACK + \brief Provider to subscriber callback function + + \param Argument An optional context argument passed to the callback + \param Type The callback type + \param Params Additional paramaters required by \a Type +*/ + +typedef VOID +(*XENVIF_VIF_CALLBACK)( + IN PVOID Argument OPTIONAL, + IN XENVIF_VIF_CALLBACK_TYPE Type, + IN PXENVIF_VIF_CALLBACK_PARAMS Params + ); + +/*! \typedef XENVIF_VIF_ENABLE_V6 \brief Enable the VIF interface All packets queued for transmit will be rejected and no packets will @@ -834,7 +893,7 @@ struct _XENVIF_VIF_INTERFACE_V6 { INTERFACE Interface; XENVIF_VIF_ACQUIRE Acquire; XENVIF_VIF_RELEASE Release; - XENVIF_VIF_ENABLE Enable; + XENVIF_VIF_ENABLE_V6 Enable; XENVIF_VIF_DISABLE Disable; XENVIF_VIF_QUERY_STATISTIC QueryStatistic; XENVIF_VIF_QUERY_RING_COUNT QueryRingCount; @@ -868,7 +927,7 @@ struct _XENVIF_VIF_INTERFACE_V7 { INTERFACE Interface; XENVIF_VIF_ACQUIRE Acquire; XENVIF_VIF_RELEASE Release; - XENVIF_VIF_ENABLE Enable; + XENVIF_VIF_ENABLE_V6 Enable; XENVIF_VIF_DISABLE Disable; XENVIF_VIF_QUERY_STATISTIC QueryStatistic; XENVIF_VIF_QUERY_RING_COUNT QueryRingCount; @@ -899,6 +958,36 @@ struct _XENVIF_VIF_INTERFACE_V7 { \ingroup interfaces */ struct _XENVIF_VIF_INTERFACE_V8 { + INTERFACE Interface; + XENVIF_VIF_ACQUIRE Acquire; + XENVIF_VIF_RELEASE Release; + XENVIF_VIF_ENABLE_V6 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 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_V9 { INTERFACE Interface; XENVIF_VIF_ACQUIRE Acquire; XENVIF_VIF_RELEASE Release; @@ -928,7 +1017,7 @@ struct _XENVIF_VIF_INTERFACE_V8 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; -typedef struct _XENVIF_VIF_INTERFACE_V8 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; +typedef struct _XENVIF_VIF_INTERFACE_V9 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; /*! \def XENVIF_VIF \brief Macro at assist in method invocation @@ -939,6 +1028,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 f8bfdd4..0c1be81 100644 --- a/src/xenvif/receiver.c +++ b/src/xenvif/receiver.c @@ -150,8 +150,6 @@ struct _XENVIF_RECEIVER { #define XENVIF_RECEIVER_TAG 'ECER' -#define RX_BUFFERING_MAX 2048 // X-ref XenNet IN_NDIS_MAX (half in NDIS half elsewhere) - static FORCEINLINE PVOID __ReceiverAllocate( IN ULONG Length @@ -1343,13 +1341,13 @@ __ReceiverRingSwizzle( LIST_ENTRY List; PLIST_ENTRY ListEntry; BOOLEAN AllFlushed; - ULONG PushedUpstream; + BOOLEAN NdisFinishedBatch; Receiver = Ring->Receiver; Frontend = Receiver->Frontend; Context = PdoGetVifContext(FrontendGetPdo(Frontend)); AllFlushed = TRUE; - PushedUpstream = 0; + NdisFinishedBatch = FALSE; InitializeListHead(&List); @@ -1388,7 +1386,7 @@ __ReceiverRingSwizzle( } while (!IsListEmpty(&Ring->PacketComplete) && - ((PushedUpstream < RX_BUFFERING_MAX) || Ring->FinalFlush)) { + (!NdisFinishedBatch || Ring->FinalFlush)) { PXENVIF_RECEIVER_PACKET Packet; PXENVIF_PACKET_INFO Info; PUCHAR BaseVa; @@ -1396,8 +1394,6 @@ __ReceiverRingSwizzle( PETHERNET_ADDRESS DestinationAddress; ETHERNET_ADDRESS_TYPE Type; - PushedUpstream++; - ListEntry = RemoveHeadList(&Ring->PacketComplete); ASSERT3P(ListEntry, !=, &Ring->PacketComplete); @@ -1543,7 +1539,7 @@ __ReceiverRingSwizzle( (VOID) InterlockedIncrement(&Receiver->Loaned); - VifReceiverQueuePacket(Context, + NdisFinishedBatch = VifReceiverQueuePacket(Context, Ring->Index, &Packet->Mdl, Packet->Offset, @@ -1553,8 +1549,7 @@ __ReceiverRingSwizzle( Packet->TagControlInformation, &Packet->Info, &Packet->Hash, - ((!IsListEmpty(&Ring->PacketComplete)) && - ((PushedUpstream < RX_BUFFERING_MAX) || Ring->FinalFlush)) ? TRUE : FALSE, + !IsListEmpty(&Ring->PacketComplete), /* Keep this in - resets counts in xennet */ Packet); } diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c index 69ced78..4aeb709 100644 --- a/src/xenvif/vif.c +++ b/src/xenvif/vif.c @@ -51,6 +51,7 @@ struct _XENVIF_VIF_CONTEXT { PXENVIF_FRONTEND Frontend; BOOLEAN Enabled; ULONG Version; + XENVIF_VIF_CALLBACK_V6 CallbackV6; XENVIF_VIF_CALLBACK Callback; PVOID Argument; PXENVIF_THREAD MacThread; @@ -106,8 +107,19 @@ VifMac( break; if (Context->Enabled) - Context->Callback(Context->Argument, - XENVIF_MAC_STATE_CHANGE); + { + if (Context->Version < 9) { + Context->CallbackV6(Context->Argument, + XENVIF_MAC_STATE_CHANGE); + } else { + XENVIF_VIF_CALLBACK_PARAMS Params; + + RtlZeroMemory(&Params, sizeof(Params)); + Context->Callback(Context->Argument, + XENVIF_MAC_STATE_CHANGE, + &Params); + } + } KeSetEvent(&Context->MacEvent, IO_NO_INCREMENT, FALSE); } @@ -138,10 +150,11 @@ VifSuspendCallbackLate( } static NTSTATUS -VifEnable( +VifEnableCommon( IN PINTERFACE Interface, - IN XENVIF_VIF_CALLBACK Callback, - IN PVOID Argument + IN PVOID Callback, + IN PVOID Argument, + IN BOOLEAN Varargs ) { PXENVIF_VIF_CONTEXT Context = Interface->Context; @@ -157,7 +170,13 @@ VifEnable( if (Context->Enabled) goto done; - Context->Callback = Callback; + if (Varargs) { + Context->CallbackV6 = (XENVIF_VIF_CALLBACK_V6) Callback; + Context->Callback = NULL; + } else { + Context->CallbackV6 = NULL; + Context->Callback = (XENVIF_VIF_CALLBACK)Callback; + } Context->Argument = Argument; Context->Enabled = TRUE; @@ -226,6 +245,7 @@ fail1: KeMemoryBarrier(); Context->Argument = NULL; + Context->CallbackV6 = NULL; Context->Callback = NULL; if (Exclusive) @@ -236,6 +256,28 @@ fail1: return status; } +static FORCEINLINE NTSTATUS +VifEnableVarargs( + IN PINTERFACE Interface, + IN XENVIF_VIF_CALLBACK_V6 Callback, + IN PVOID Argument + ) { + BUG_ON(Interface->Version >= 9); + + return VifEnableCommon(Interface, (PVOID)Callback, Argument, TRUE); +} + +static FORCEINLINE NTSTATUS +VifEnableParams( + IN PINTERFACE Interface, + IN XENVIF_VIF_CALLBACK Callback, + IN PVOID Argument + ) { + BUG_ON(Interface->Version < 9); + + return VifEnableCommon(Interface, (PVOID)Callback, Argument, FALSE); +} + static VOID VifDisable( IN PINTERFACE Interface @@ -285,6 +327,7 @@ VifDisable( XENBUS_SUSPEND(Release, &Context->SuspendInterface); Context->Argument = NULL; + Context->CallbackV6 = NULL; Context->Callback = NULL; ReleaseMrswLockShared(&Context->Lock); @@ -832,7 +875,7 @@ static struct _XENVIF_VIF_INTERFACE_V6 VifInterfaceVersion6 = { { sizeof (struct _XENVIF_VIF_INTERFACE_V6), 6, NULL, NULL, NULL }, VifAcquire, VifRelease, - VifEnable, + VifEnableVarargs, VifDisable, VifQueryStatistic, VifQueryRingCount, @@ -862,7 +905,7 @@ static struct _XENVIF_VIF_INTERFACE_V7 VifInterfaceVersion7 = { { sizeof (struct _XENVIF_VIF_INTERFACE_V7), 7, NULL, NULL, NULL }, VifAcquire, VifRelease, - VifEnable, + VifEnableVarargs, VifDisable, VifQueryStatistic, VifQueryRingCount, @@ -892,7 +935,37 @@ static struct _XENVIF_VIF_INTERFACE_V8 VifInterfaceVersion8 = { { sizeof (struct _XENVIF_VIF_INTERFACE_V8), 8, NULL, NULL, NULL }, VifAcquire, VifRelease, - VifEnable, + VifEnableVarargs, + 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_V9 VifInterfaceVersion9 = { + { sizeof (struct _XENVIF_VIF_INTERFACE_V9), 9, NULL, NULL, NULL }, + VifAcquire, + VifRelease, + VifEnableParams, VifDisable, VifQueryStatistic, VifQueryRingCount, @@ -1033,6 +1106,23 @@ VifGetInterface( status = STATUS_SUCCESS; break; } + case 9: { + struct _XENVIF_VIF_INTERFACE_V9 *VifInterface; + + VifInterface = (struct _XENVIF_VIF_INTERFACE_V9 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof (struct _XENVIF_VIF_INTERFACE_V9)) + break; + + *VifInterface = VifInterfaceVersion9; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; @@ -1087,7 +1177,7 @@ __VifReceiverQueuePacketVersion6( UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(More); - Context->Callback(Context->Argument, + Context->CallbackV6(Context->Argument, XENVIF_RECEIVER_QUEUE_PACKET, Mdl, Offset, @@ -1118,7 +1208,7 @@ __VifReceiverQueuePacketVersion7( { UNREFERENCED_PARAMETER(Index); - Context->Callback(Context->Argument, + Context->CallbackV6(Context->Argument, XENVIF_RECEIVER_QUEUE_PACKET, Mdl, Offset, @@ -1133,7 +1223,7 @@ __VifReceiverQueuePacketVersion7( } static FORCEINLINE VOID -__VifReceiverQueuePacket( +__VifReceiverQueuePacketVersion8( IN PXENVIF_VIF_CONTEXT Context, IN ULONG Index, IN PMDL Mdl, @@ -1148,7 +1238,7 @@ __VifReceiverQueuePacket( IN PVOID Cookie ) { - Context->Callback(Context->Argument, + Context->CallbackV6(Context->Argument, XENVIF_RECEIVER_QUEUE_PACKET, Index, Mdl, @@ -1164,7 +1254,48 @@ __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 + ) +{ + XENVIF_VIF_CALLBACK_PARAMS Params; + BOOLEAN Finished = FALSE; + + RtlZeroMemory(&Params, sizeof(Params)); + + Params.QueuePacketParams.Index = Index; + Params.QueuePacketParams.Mdl = Mdl; + Params.QueuePacketParams.Offset = Offset; + Params.QueuePacketParams.Length = Length; + Params.QueuePacketParams.Flags = Flags; + Params.QueuePacketParams.MaximumSegmentSize = MaximumSegmentSize; + Params.QueuePacketParams.TagControlInformation = TagControlInformation; + Params.QueuePacketParams.Info = Info; + Params.QueuePacketParams.Hash = Hash; + Params.QueuePacketParams.More = More; + Params.QueuePacketParams.Cookie = Cookie; + Params.QueuePacketParams.NdisFinished = &Finished; + + Context->Callback(Context->Argument, + XENVIF_RECEIVER_QUEUE_PACKET, + &Params); + return Finished; +} + + +BOOLEAN /* Returns NDIS finished batch for this DPC */ VifReceiverQueuePacket( IN PXENVIF_VIF_CONTEXT Context, IN ULONG Index, @@ -1181,6 +1312,7 @@ VifReceiverQueuePacket( ) { KIRQL Irql; + BOOLEAN Finished = FALSE; KeRaiseIrql(DISPATCH_LEVEL, &Irql); @@ -1216,7 +1348,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 +1383,8 @@ VifReceiverQueuePacket( } KeLowerIrql(Irql); + + return Finished; } VOID @@ -1245,20 +1394,24 @@ 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; - } + if (Context->Version < 9) { + Context->CallbackV6(Context->Argument, + XENVIF_TRANSMITTER_RETURN_PACKET, + Cookie, + Completion); + } else { + XENVIF_VIF_CALLBACK_PARAMS Params; + + RtlZeroMemory(&Params, sizeof(Params)); + Params.ReturnPacketParams.Cookie = Cookie; + Params.ReturnPacketParams.Completion = Completion; + + Context->Callback(Context->Argument, + XENVIF_TRANSMITTER_RETURN_PACKET, + &Params); + } } 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |