[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 02/10] Add VIF interface version 2
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- include/vif_interface.h | 84 ++++++++++++++++++++++-- src/xenvif/transmitter.c | 164 ++++++++++++++++++++++++++++++++++++++++------- src/xenvif/transmitter.h | 17 +++++ src/xenvif/vif.c | 145 +++++++++++++++++++++++++++++++++++++++-- src/xenvif/vif.h | 11 ++++ 5 files changed, 386 insertions(+), 35 deletions(-) diff --git a/include/vif_interface.h b/include/vif_interface.h index 8bde731..4ce61c4 100644 --- a/include/vif_interface.h +++ b/include/vif_interface.h @@ -116,6 +116,7 @@ struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 { }; }; + typedef struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 XENVIF_PACKET_CHECKSUM_FLAGS, *PXENVIF_PACKET_CHECKSUM_FLAGS; #pragma warning(pop) @@ -269,17 +270,25 @@ C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof (PVOID))); \brief Transmit-side packet structure */ struct _XENVIF_TRANSMITTER_PACKET_V2 { + /*! List entry used for chaining packets together */ LIST_ENTRY ListEntry; + /*! MDL referencing the packet's buffer */ PMDL Mdl; + /*! Offset of start of packet in MDL */ ULONG Offset; + /*! Total length of packet */ ULONG Length; + /*! Opaque cookie used to store context information for packet return */ PVOID Cookie; + /*! Packet information passed down to subscriber */ XENVIF_TRANSMITTER_PACKET_SEND_INFO Send; + /*! Information passed up from subscriber for packet completion */ XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO Completion; }; typedef struct _XENVIF_TRANSMITTER_PACKET_V2 XENVIF_TRANSMITTER_PACKET_V2, *PXENVIF_TRANSMITTER_PACKET_V2; + /*! \enum _XENVIF_TRANSMITTER_PACKET_OFFSET \brief Offsets of packet metadata relative to XENVIF_TRANSMITTER_PACKET_V1 pointer @@ -501,6 +510,34 @@ typedef NTSTATUS IN PXENVIF_TRANSMITTER_PACKET_V1 Head ); +/*! \typedef XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2 + \brief Queue transmit side packets at the provider + + \param Interface The interface header + \param List List of XENVIF_TRANSMITTER_PACKET_V2 +*/ +typedef NTSTATUS +(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2)( + IN PINTERFACE Interface, + IN PLIST_ENTRY List + ); + +/*! \typedef XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS + \brief Get a copy of the packet headers and each the offset of each + + \param Interface The interface header +*/ +typedef NTSTATUS +(*XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS)( + IN PINTERFACE Interface, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + OUT PVOID HeaderBuffer, + IN ULONG HeaderLength, + OUT PXENVIF_PACKET_INFO Info + ); + /*! \typedef XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS \brief Query the available set of transmit side offload options @@ -694,10 +731,6 @@ typedef NTSTATUS DEFINE_GUID(GUID_XENVIF_VIF_INTERFACE, 0x76f279cd, 0xca11, 0x418b, 0x92, 0xe8, 0xc5, 0x7f, 0x77, 0xde, 0xe, 0x2e); -/*! \struct _XENVIF_VIF_INTERFACE_V1 - \brief VIF interface version 1 - \ingroup interfaces -*/ struct _XENVIF_VIF_INTERFACE_V1 { INTERFACE Interface; XENVIF_VIF_ACQUIRE Acquire; @@ -723,17 +756,54 @@ struct _XENVIF_VIF_INTERFACE_V1 { XENVIF_VIF_MAC_QUERY_FILTER_LEVEL MacQueryFilterLevel; }; -typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; +typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE_V1, *PXENVIF_VIF_INTERFACE_V1; + +struct _XENVIF_VIF_INTERFACE_V2 { + 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_RECEIVER_RETURN_PACKETS ReceiverReturnPackets; + XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS ReceiverSetOffloadOptions; + XENVIF_VIF_RECEIVER_QUERY_RING_SIZE ReceiverQueryRingSize; + XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET TransmitterSetPacketOffset; // obsolete + XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V1 TransmitterQueuePackets; // obsolete + 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; + XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS_V2 TransmitterQueuePacketsV2; + XENVIF_VIF_TRANSMITTER_GET_PACKET_HEADERS TransmitterGetPacketHeaders; +}; + +typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE_V2, *PXENVIF_VIF_INTERFACE_V2; + +typedef struct _XENVIF_VIF_INTERFACE_V2 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE; /*! \def XENVIF_VIF - \brief Macro at assist in method invocation + \brief Macro to assist in method invocation */ #define XENVIF_VIF(_Method, _Interface, ...) \ (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__) +/*! \def XENVIF_VIF_VERSION + \brief Macro to assist in getting interface version in use +*/ +#define XENVIF_VIF_VERSION(_Interface) \ + ((_Interface)->Interface.Version) + #endif // _WINDLL #define XENVIF_VIF_INTERFACE_VERSION_MIN 1 -#define XENVIF_VIF_INTERFACE_VERSION_MAX 1 +#define XENVIF_VIF_INTERFACE_VERSION_MAX 2 #endif // _XENVIF_INTERFACE_H diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c index 38e4cb2..6fd542e 100644 --- a/src/xenvif/transmitter.c +++ b/src/xenvif/transmitter.c @@ -2386,33 +2386,44 @@ TransmitterReturnPackets( IN PLIST_ENTRY List ) { - PXENVIF_FRONTEND Frontend; - PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket; - PXENVIF_TRANSMITTER_PACKET_V1 NextPacket; + PXENVIF_VIF_CONTEXT Context; + + Context = PdoGetVifContext(FrontendGetPdo(Transmitter->Frontend)); - HeadPacket = NULL; - NextPacket = NULL; - while (!IsListEmpty(List)) { - PLIST_ENTRY ListEntry; - PXENVIF_TRANSMITTER_PACKET_V2 Packet; + switch (VifGetVersion(Context)) { + case 1: { + PXENVIF_TRANSMITTER_PACKET_V1 HeadPacket; + PXENVIF_TRANSMITTER_PACKET_V1 NextPacket; - ListEntry = RemoveTailList(List); - ASSERT3P(ListEntry, !=, List); + HeadPacket = NULL; + NextPacket = NULL; + while (!IsListEmpty(List)) { + PLIST_ENTRY ListEntry; + PXENVIF_TRANSMITTER_PACKET_V2 Packet; - Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2, ListEntry); + ListEntry = RemoveTailList(List); + ASSERT3P(ListEntry, !=, List); - HeadPacket = Packet->Cookie; - HeadPacket->Next = NextPacket; - HeadPacket->Completion = Packet->Completion; + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET_V2, ListEntry); - __TransmitterPutPacket(Transmitter, Packet); - NextPacket = HeadPacket; - } + HeadPacket = Packet->Cookie; + HeadPacket->Next = NextPacket; + HeadPacket->Completion = Packet->Completion; - Frontend = Transmitter->Frontend; + __TransmitterPutPacket(Transmitter, Packet); + NextPacket = HeadPacket; + } - VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)), - HeadPacket); + VifTransmitterReturnPackets(Context, HeadPacket); + break; + } + case 2: + VifTransmitterReturnPacketsV2(Context, List); + break; + default: + ASSERT(FALSE); + break; + } } static FORCEINLINE BOOLEAN @@ -3803,9 +3814,9 @@ TransmitterQueuePacketsV1( // if HeadPacket != NULL, errors occured and need returning if (HeadPacket != NULL) { PXENVIF_TRANSMITTER_PACKET_V1 Packet; - PXENVIF_FRONTEND Frontend; + PXENVIF_VIF_CONTEXT Context; - Frontend = Transmitter->Frontend; + Context = PdoGetVifContext(FrontendGetPdo(Transmitter->Frontend)); Packet = HeadPacket; while (Packet != NULL) { @@ -3813,8 +3824,7 @@ TransmitterQueuePacketsV1( Packet = Packet->Next; } - VifTransmitterReturnPackets(PdoGetVifContext(FrontendGetPdo(Frontend)), - HeadPacket); + VifTransmitterReturnPackets(Context, HeadPacket); } #undef OFFSET @@ -3822,6 +3832,112 @@ TransmitterQueuePacketsV1( } VOID +TransmitterQueuePacketsV2( + IN PXENVIF_TRANSMITTER Transmitter, + IN PLIST_ENTRY List + ) +{ + PLIST_ENTRY ListEntry; + PXENVIF_TRANSMITTER_RING Ring; + + // We need to hash for a ring eventually. Since there is only a + // single ring for now, we just use that. + ListEntry = Transmitter->List.Flink; + Ring = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_RING, ListEntry); + + __TransmitterRingQueuePackets(Ring, List); +} + +static BOOLEAN +TransmitterHeaderPullup( + IN PVOID Argument, + IN PUCHAR DestinationVa, + IN PXENVIF_PACKET_PAYLOAD Payload, + IN ULONG Length + ) +{ + PMDL Mdl; + ULONG Offset; + + UNREFERENCED_PARAMETER(Argument); + + Mdl = Payload->Mdl; + Offset = Payload->Offset; + + if (Payload->Length < Length) + goto fail1; + + Payload->Length -= Length; + + while (Length != 0) { + PUCHAR MdlMappedSystemVa; + ULONG MdlByteCount; + ULONG CopyLength; + + ASSERT(Mdl != NULL); + + MdlMappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + ASSERT(MdlMappedSystemVa != NULL); + + MdlMappedSystemVa += Offset; + + MdlByteCount = Mdl->ByteCount - Offset; + + CopyLength = __min(MdlByteCount, Length); + + RtlCopyMemory(DestinationVa, MdlMappedSystemVa, CopyLength); + DestinationVa += CopyLength; + + Offset += CopyLength; + Length -= CopyLength; + + MdlByteCount -= CopyLength; + if (MdlByteCount == 0) { + Mdl = Mdl->Next; + Offset = 0; + } + } + + Payload->Mdl = Mdl; + Payload->Offset = Offset; + + return TRUE; + +fail1: + Error("fail1\n"); + + return FALSE; +} + +NTSTATUS +TransmitterGetPacketHeaders( + IN PXENVIF_TRANSMITTER Transmitter, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + OUT PVOID HeaderBuffer, + IN ULONG HeaderLength, + OUT PXENVIF_PACKET_INFO Info + ) +{ + XENVIF_PACKET_PAYLOAD Payload; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Transmitter); + + Payload.Mdl = Mdl; + Payload.Offset = Offset; + Payload.Length = Length; + + status = ParsePacket(HeaderBuffer, + TransmitterHeaderPullup, + &HeaderLength, + &Payload, + Info); + return status; +} + +VOID TransmitterAbortPackets( IN PXENVIF_TRANSMITTER Transmitter ) diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h index 661eeae..c359c20 100644 --- a/src/xenvif/transmitter.h +++ b/src/xenvif/transmitter.h @@ -113,6 +113,23 @@ TransmitterQueuePacketsV1( ); extern VOID +TransmitterQueuePacketsV2( + IN PXENVIF_TRANSMITTER Transmitter, + IN PLIST_ENTRY List + ); + +extern NTSTATUS +TransmitterGetPacketHeaders( + IN PXENVIF_TRANSMITTER Transmitter, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + OUT PVOID HeaderBuffer, + IN ULONG HeaderLength, + OUT PXENVIF_PACKET_INFO Info + ); + +extern VOID TransmitterQueryOffloadOptions( IN PXENVIF_TRANSMITTER Transmitter, OUT PXENVIF_VIF_OFFLOAD_OPTIONS Options diff --git a/src/xenvif/vif.c b/src/xenvif/vif.c index d6da258..8c1156a 100644 --- a/src/xenvif/vif.c +++ b/src/xenvif/vif.c @@ -46,6 +46,7 @@ struct _XENVIF_VIF_CONTEXT { PXENVIF_PDO Pdo; XENVIF_MRSW_LOCK Lock; LONG References; + ULONG Version; PXENVIF_FRONTEND Frontend; BOOLEAN Enabled; XENVIF_VIF_CALLBACK Callback; @@ -302,6 +303,75 @@ fail1: return status; } +static NTSTATUS +VifTransmitterQueuePacketsV2( + IN PINTERFACE Interface, + IN PLIST_ENTRY List + ) +{ + PXENVIF_VIF_CONTEXT Context = Interface->Context; + NTSTATUS status; + + AcquireMrswLockShared(&Context->Lock); + + status = STATUS_UNSUCCESSFUL; + if (Context->Enabled == FALSE) + goto fail1; + + TransmitterQueuePacketsV2(FrontendGetTransmitter(Context->Frontend), + List); + + ReleaseMrswLockShared(&Context->Lock); + + return STATUS_SUCCESS; + +fail1: + ReleaseMrswLockShared(&Context->Lock); + + return status; +} + +static NTSTATUS +VifTransmitterGetPacketHeaders( + IN PINTERFACE Interface, + IN PMDL Mdl, + IN ULONG Offset, + IN ULONG Length, + OUT PVOID HeaderBuffer, + IN ULONG HeaderLength, + OUT PXENVIF_PACKET_INFO Info + ) +{ + PXENVIF_VIF_CONTEXT Context = Interface->Context; + NTSTATUS status; + + AcquireMrswLockShared(&Context->Lock); + + status = STATUS_UNSUCCESSFUL; + if (Context->Enabled == FALSE) + goto fail1; + + status = TransmitterGetPacketHeaders(FrontendGetTransmitter(Context->Frontend), + Mdl, + Offset, + Length, + HeaderBuffer, + HeaderLength, + Info); + if (!NT_SUCCESS(status)) + goto fail2; + + ReleaseMrswLockShared(&Context->Lock); + + return STATUS_SUCCESS; + +fail2: +fail1: + ReleaseMrswLockShared(&Context->Lock); + + return status; +} + static VOID VifTransmitterQueryOffloadOptions( IN PINTERFACE Interface, @@ -560,7 +630,9 @@ VifAcquire( if (Context->References++ != 0) goto done; - Trace("====>\n"); + Trace("====> (%u)\n", Interface->Version); + + Context->Version = Interface->Version; status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface); if (!NT_SUCCESS(status)) @@ -577,7 +649,7 @@ VifAcquire( Context->Frontend = PdoGetFrontend(Context->Pdo); - Trace("<====\n"); + Trace("<==== (%u)\n", Interface->Version); done: ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE); @@ -612,7 +684,7 @@ VifRelease( if (--Context->References > 0) goto done; - Trace("====>\n"); + Trace("====> (%u)\n", Interface->Version); ASSERT(!Context->Enabled); @@ -625,7 +697,9 @@ VifRelease( XENBUS_SUSPEND(Release, &Context->SuspendInterface); - Trace("<====\n"); + Context->Version = 0; + + Trace("<==== (%u)\n", Interface->Version); done: ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE); @@ -656,6 +730,33 @@ static struct _XENVIF_VIF_INTERFACE_V1 VifInterfaceVersion1 = { VifMacQueryFilterLevel }; +static struct _XENVIF_VIF_INTERFACE_V2 VifInterfaceVersion2 = { + { sizeof (struct _XENVIF_VIF_INTERFACE_V2), 2, NULL, NULL, NULL }, + VifAcquire, + VifRelease, + VifEnable, + VifDisable, + VifQueryStatistic, + VifReceiverReturnPackets, + VifReceiverSetOffloadOptions, + VifReceiverQueryRingSize, + VifTransmitterSetPacketOffset, + VifTransmitterQueuePackets, + VifTransmitterQueryOffloadOptions, + VifTransmitterQueryLargePacketSize, + VifTransmitterQueryRingSize, + VifMacQueryState, + VifMacQueryMaximumFrameSize, + VifMacQueryPermanentAddress, + VifMacQueryCurrentAddress, + VifMacQueryMulticastAddresses, + VifMacSetMulticastAddresses, + VifMacSetFilterLevel, + VifMacQueryFilterLevel, + VifTransmitterQueuePacketsV2, + VifTransmitterGetPacketHeaders +}; + NTSTATUS VifInitialize( IN PXENVIF_PDO Pdo, @@ -737,6 +838,23 @@ VifGetInterface( status = STATUS_SUCCESS; break; } + case 2: { + struct _XENVIF_VIF_INTERFACE_V2 *VifInterface; + + VifInterface = (struct _XENVIF_VIF_INTERFACE_V2 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof(struct _XENVIF_VIF_INTERFACE_V2)) + break; + + *VifInterface = VifInterfaceVersion2; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; @@ -793,6 +911,25 @@ VifTransmitterReturnPackets( Head); } +VOID +VifTransmitterReturnPacketsV2( + IN PXENVIF_VIF_CONTEXT Context, + IN PLIST_ENTRY List + ) +{ + Context->Callback(Context->Argument, + XENVIF_TRANSMITTER_RETURN_PACKETS, + List); +} + +ULONG +VifGetVersion( + IN PXENVIF_VIF_CONTEXT Context + ) +{ + return Context->Version; +} + extern PXENVIF_THREAD VifGetMacThread( IN PXENVIF_VIF_CONTEXT Context diff --git a/src/xenvif/vif.h b/src/xenvif/vif.h index 0ef6687..fe0f9e4 100644 --- a/src/xenvif/vif.h +++ b/src/xenvif/vif.h @@ -74,10 +74,21 @@ VifTransmitterReturnPackets( IN PXENVIF_TRANSMITTER_PACKET_V1 Head ); +extern VOID +VifTransmitterReturnPacketsV2( + IN PXENVIF_VIF_CONTEXT Context, + IN PLIST_ENTRY List + ); + extern PXENVIF_THREAD VifGetMacThread( IN PXENVIF_VIF_CONTEXT Context ); +extern ULONG +VifGetVersion( + IN PXENVIF_VIF_CONTEXT Context + ); + #endif // _XENVIF_VIF_H -- 1.9.4.msysgit.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |