[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 7/7] Implement multiple queues
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvif/driver.c | 42 ++++++++++ src/xenvif/driver.h | 5 ++ src/xenvif/frontend.c | 114 ++++++++++++++++++++++++++- src/xenvif/frontend.h | 11 +++ src/xenvif/receiver.c | 117 +++++++++++++++++++++------- src/xenvif/receiver.h | 1 - src/xenvif/transmitter.c | 198 ++++++++++++++++++++++++++++++++++++----------- src/xenvif/transmitter.h | 1 - 8 files changed, 409 insertions(+), 80 deletions(-) diff --git a/src/xenvif/driver.c b/src/xenvif/driver.c index 6f81620..083fa19 100644 --- a/src/xenvif/driver.c +++ b/src/xenvif/driver.c @@ -47,6 +47,7 @@ typedef struct _XENVIF_DRIVER { PDRIVER_OBJECT DriverObject; HANDLE ParametersKey; HANDLE AddressesKey; + ULONG MaximumQueues; } XENVIF_DRIVER, *PXENVIF_DRIVER; static XENVIF_DRIVER Driver; @@ -123,6 +124,30 @@ DriverGetAddressesKey( return __DriverGetAddressesKey(); } +static FORCEINLINE VOID +__DriverSetMaximumQueueCount( + IN ULONG Count + ) +{ + Driver.MaximumQueues = Count; +} + +static FORCEINLINE ULONG +__DriverGetMaximumQueueCount( + VOID + ) +{ + return Driver.MaximumQueues; +} + +ULONG +DriverGetMaximumQueueCount( + VOID + ) +{ + return __DriverGetMaximumQueueCount(); +} + DRIVER_UNLOAD DriverUnload; VOID @@ -148,6 +173,8 @@ DriverUnload( ParametersKey = __DriverGetParametersKey(); __DriverSetParametersKey(NULL); + __DriverSetMaximumQueueCount(0); + RegistryCloseKey(ParametersKey); RegistryTeardown(); @@ -254,6 +281,8 @@ DriverEntry( HANDLE ParametersKey; HANDLE AddressesKey; ULONG Index; + ULONG MaxQueues; + ULONG Processors; NTSTATUS status; ASSERT3P(__DriverGetDriverObject(), ==, NULL); @@ -295,6 +324,8 @@ DriverEntry( if (!NT_SUCCESS(status)) goto fail3; + __DriverSetParametersKey(ParametersKey); + status = RegistryCreateSubKey(ServiceKey, "Addresses", REG_OPTION_VOLATILE, @@ -304,6 +335,17 @@ DriverEntry( __DriverSetAddressesKey(AddressesKey); + status = RegistryQueryDwordValue(ParametersKey, + "MultiQueueMaxQueues", + &MaxQueues); + if (!NT_SUCCESS(status)) + MaxQueues = MAXIMUM_PROCESSORS; + + Processors = KeQueryActiveProcessorCount(NULL); + __DriverSetMaximumQueueCount(MaxQueues > Processors ? + Processors : + MaxQueues); + RegistryCloseKey(ServiceKey); DriverObject->DriverExtension->AddDevice = AddDevice; diff --git a/src/xenvif/driver.h b/src/xenvif/driver.h index cdef7d1..bbea23b 100644 --- a/src/xenvif/driver.h +++ b/src/xenvif/driver.h @@ -52,6 +52,11 @@ DriverGetAliasesKey( VOID ); +extern ULONG +DriverGetMaximumQueueCount( + VOID + ); + typedef struct _XENVIF_PDO XENVIF_PDO, *PXENVIF_PDO; typedef struct _XENVIF_FDO XENVIF_FDO, *PXENVIF_FDO; diff --git a/src/xenvif/frontend.c b/src/xenvif/frontend.c index 268bab9..cfe6220 100644 --- a/src/xenvif/frontend.c +++ b/src/xenvif/frontend.c @@ -63,6 +63,7 @@ struct _XENVIF_FRONTEND { PCHAR BackendPath; USHORT BackendDomain; + ULONG QueueCount; PXENVIF_GRANTER Granter; PXENVIF_MAC Mac; @@ -201,6 +202,67 @@ FrontendGetBackendDomain( return __FrontendGetBackendDomain(Frontend); } +static FORCEINLINE VOID +__FrontendSetQueueCount( + IN PXENVIF_FRONTEND Frontend, + IN ULONG Count + ) +{ + Frontend->QueueCount = Count; +} + +static FORCEINLINE ULONG +__FrontendGetQueueCount( + IN PXENVIF_FRONTEND Frontend + ) +{ + return Frontend->QueueCount; +} + +ULONG +FrontendGetQueueCount( + IN PXENVIF_FRONTEND Frontend + ) +{ + return __FrontendGetQueueCount(Frontend); +} + +PCHAR +FrontendFormatPath( + IN PXENVIF_FRONTEND Frontend, + IN ULONG Index + ) +{ + ULONG Length; + PCHAR Path; + NTSTATUS status; + + Length = (ULONG)strlen(FrontendGetPath(Frontend)) + + (ULONG)strlen("/queue-00") + + 1; + + Path = ExAllocatePoolWithTag(NonPagedPool, + Length * sizeof(CHAR), + 'HTAP'); + if (Path == NULL) + goto fail1; + + status = RtlStringCchPrintfA(Path, + Length, + "%s/queue-%u", + FrontendGetPath(Frontend), + Index); + if (!NT_SUCCESS(status)) + goto fail2; + + return Path; + +fail2: + ExFreePoolWithTag(Path, 'HTAP'); +fail1: + return NULL; +} + #define DEFINE_FRONTEND_GET_FUNCTION(_Function, _Type) \ static FORCEINLINE _Type \ __FrontendGet ## _Function( \ @@ -1274,6 +1336,42 @@ FrontendDebugCallback( } } +static FORCEINLINE VOID +__FrontendReadQueueCount( + IN PXENVIF_FRONTEND Frontend + ) +{ + PCHAR Buffer; + ULONG Value; + NTSTATUS status; + + // default to 1 queue. + // backend must advertise "multi-queue-max-queues" to enable + // multi-queue support. + Value = 1; + + status = XENBUS_STORE(Read, + &Frontend->StoreInterface, + NULL, + __FrontendGetBackendPath(Frontend), + "multi-queue-max-queues", + &Buffer); + if (NT_SUCCESS(status)) { + Value = (ULONG)strtoul(Buffer, NULL, 10); + + XENBUS_STORE(Free, + &Frontend->StoreInterface, + Buffer); + + // set value to minimum of what frontend supports (vCPUs) and + // what backend supports (Dom0 vCPUs) + if (Value > DriverGetMaximumQueueCount()) + Value = DriverGetMaximumQueueCount(); + } + + __FrontendSetQueueCount(Frontend, Value); +} + static FORCEINLINE NTSTATUS __FrontendConnect( IN PXENVIF_FRONTEND Frontend @@ -1307,6 +1405,7 @@ __FrontendConnect( if (!NT_SUCCESS(status)) goto fail4; + __FrontendReadQueueCount(Frontend); status = ReceiverConnect(__FrontendGetReceiver(Frontend)); if (!NT_SUCCESS(status)) goto fail5; @@ -1335,6 +1434,16 @@ __FrontendConnect( if (!NT_SUCCESS(status)) goto abort; + status = XENBUS_STORE(Printf, + &Frontend->StoreInterface, + Transaction, + __FrontendGetPath(Frontend), + "multi-queue-num-queues", + "%u", + __FrontendGetQueueCount(Frontend)); + if (!NT_SUCCESS(status)) + goto abort; + status = XENBUS_STORE(TransactionEnd, &Frontend->StoreInterface, Transaction, @@ -1870,11 +1979,11 @@ FrontendInitialize( if (!NT_SUCCESS(status)) goto fail7; - status = ReceiverInitialize(*Frontend, 1, &(*Frontend)->Receiver); + status = ReceiverInitialize(*Frontend, &(*Frontend)->Receiver); if (!NT_SUCCESS(status)) goto fail8; - status = TransmitterInitialize(*Frontend, 1, &(*Frontend)->Transmitter); + status = TransmitterInitialize(*Frontend, &(*Frontend)->Transmitter); if (!NT_SUCCESS(status)) goto fail9; @@ -2021,6 +2130,7 @@ FrontendTeardown( RtlZeroMemory(&Frontend->Lock, sizeof (KSPIN_LOCK)); Frontend->BackendDomain = 0; + __FrontendSetQueueCount(Frontend, 0); __FrontendFree(Frontend->Prefix); Frontend->Prefix = NULL; diff --git a/src/xenvif/frontend.h b/src/xenvif/frontend.h index 67696d6..5d2905d 100644 --- a/src/xenvif/frontend.h +++ b/src/xenvif/frontend.h @@ -112,6 +112,17 @@ FrontendGetBackendDomain( IN PXENVIF_FRONTEND Frontend ); +extern ULONG +FrontendGetQueueCount( + IN PXENVIF_FRONTEND Frontend + ); + +extern PCHAR +FrontendFormatPath( + IN PXENVIF_FRONTEND Frontend, + IN ULONG Index + ); + #include "granter.h" extern PXENVIF_GRANTER diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c index a11d91e..aad88e2 100644 --- a/src/xenvif/receiver.c +++ b/src/xenvif/receiver.c @@ -76,6 +76,7 @@ typedef struct _XENVIF_RECEIVER_FRAGMENT { typedef struct _XENVIF_RECEIVER_RING { PXENVIF_RECEIVER Receiver; ULONG Index; + PCHAR FrontendPath; KSPIN_LOCK Lock; PXENBUS_CACHE PacketCache; PXENBUS_CACHE FragmentCache; @@ -2045,6 +2046,11 @@ __ReceiverRingInitialize( (*Ring)->Receiver = Receiver; (*Ring)->Index = Index; + (*Ring)->FrontendPath = FrontendFormatPath(Frontend, + Index); + if ((*Ring)->FrontendPath == NULL) + goto fail2; + InitializeListHead(&(*Ring)->PacketList); KeInitializeSpinLock(&(*Ring)->EvtchnLock); @@ -2052,10 +2058,11 @@ __ReceiverRingInitialize( status = RtlStringCbPrintfA(Name, sizeof (Name), - "%s_receiver_packet", - FrontendGetPath(Frontend)); + "%s_%u_receiver_packet", + FrontendGetPath(Frontend), + (*Ring)->Index); if (!NT_SUCCESS(status)) - goto fail2; + goto fail3; for (Index = 0; Name[Index] != '\0'; Index++) if (Name[Index] == '/') @@ -2073,14 +2080,15 @@ __ReceiverRingInitialize( *Ring, &(*Ring)->PacketCache); if (!NT_SUCCESS(status)) - goto fail3; + goto fail4; status = RtlStringCbPrintfA(Name, sizeof (Name), - "%s_receiver_fragment", - FrontendGetPath(Frontend)); + "%s_%u_receiver_fragment", + FrontendGetPath(Frontend), + (*Ring)->Index); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; for (Index = 0; Name[Index] != '\0'; Index++) if (Name[Index] == '/') @@ -2098,46 +2106,52 @@ __ReceiverRingInitialize( *Ring, &(*Ring)->FragmentCache); if (!NT_SUCCESS(status)) - goto fail5; + goto fail6; status = ThreadCreate(ReceiverRingWatchdog, *Ring, &(*Ring)->WatchdogThread); if (!NT_SUCCESS(status)) - goto fail6; + goto fail7; return STATUS_SUCCESS; -fail6: - Error("fail6\n"); +fail7: + Error("fail7\n"); XENBUS_CACHE(Destroy, &Receiver->CacheInterface, (*Ring)->FragmentCache); (*Ring)->FragmentCache = NULL; +fail6: + Error("fail6\n"); + fail5: Error("fail5\n"); - -fail4: - Error("fail4\n"); XENBUS_CACHE(Destroy, &Receiver->CacheInterface, (*Ring)->PacketCache); (*Ring)->PacketCache = NULL; +fail4: + Error("fail4\n"); + fail3: Error("fail3\n"); - -fail2: - Error("fail2\n"); RtlZeroMemory(&(*Ring)->EvtchnLock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC)); RtlZeroMemory(&(*Ring)->PacketList, sizeof (LIST_ENTRY)); + ExFreePool((*Ring)->FrontendPath); // 'HTAP' + (*Ring)->FrontendPath = NULL; + +fail2: + Error("fail2\n"); + (*Ring)->Index = 0; (*Ring)->Receiver = NULL; @@ -2216,6 +2230,16 @@ __ReceiverRingConnect( goto fail4; } + if (FrontendGetQueueCount(Frontend) > 1) { + (VOID) XENBUS_EVTCHN(Bind, + &Receiver->EvtchnInterface, + Ring->Channel, + Ring->Index); + + KeSetTargetProcessorDpc(&Ring->Dpc, + (CCHAR)Ring->Index); + } + Pending = XENBUS_EVTCHN(Unmask, &Receiver->EvtchnInterface, Ring->Channel, @@ -2287,15 +2311,20 @@ __ReceiverRingStoreWrite( PXENVIF_RECEIVER Receiver; PXENVIF_FRONTEND Frontend; ULONG Port; + PCHAR Path; NTSTATUS status; Receiver = Ring->Receiver; Frontend = Receiver->Frontend; + Path = (FrontendGetQueueCount(Frontend) == 1) ? + FrontendGetPath(Frontend) : + Ring->FrontendPath; + status = XENBUS_STORE(Printf, &Receiver->StoreInterface, Transaction, - FrontendGetPath(Frontend), + Path, "rx-ring-ref", "%u", GranterGetReference(FrontendGetGranter(Frontend), @@ -2311,7 +2340,7 @@ __ReceiverRingStoreWrite( status = XENBUS_STORE(Printf, &Receiver->StoreInterface, Transaction, - FrontendGetPath(Frontend), + Path, Receiver->Split ? "event-channel-rx" : "event-channel", "%u", Port); @@ -2466,6 +2495,9 @@ __ReceiverRingTeardown( ASSERT(IsListEmpty(&Ring->PacketList)); RtlZeroMemory(&Ring->PacketList, sizeof (LIST_ENTRY)); + ExFreePool(Ring->FrontendPath); // 'HTAP' + Ring->FrontendPath = NULL; + Ring->Index = 0; Ring->Receiver = NULL; @@ -2512,14 +2544,15 @@ ReceiverDebugCallback( NTSTATUS ReceiverInitialize( IN PXENVIF_FRONTEND Frontend, - IN ULONG Count, OUT PXENVIF_RECEIVER *Receiver ) { HANDLE ParametersKey; ULONG Index; + ULONG Count; NTSTATUS status; + Count = DriverGetMaximumQueueCount(); *Receiver = __ReceiverAllocate(sizeof (XENVIF_RECEIVER)); status = STATUS_NO_MEMORY; @@ -2624,7 +2657,7 @@ fail3: (*Receiver)->Rings[Index] = NULL; if (Ring == NULL) - continue; + continue; // ensure all rings are destroyed __ReceiverRingTeardown(Ring); } @@ -2674,6 +2707,7 @@ ReceiverConnect( { PXENVIF_FRONTEND Frontend; ULONG Index; + ULONG Count; PCHAR Buffer; NTSTATUS status; @@ -2707,7 +2741,10 @@ ReceiverConnect( Buffer); } - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2736,7 +2773,7 @@ fail5: fail4: Error("fail4\n"); - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2856,6 +2893,7 @@ ReceiverStoreWrite( { PXENVIF_FRONTEND Frontend; ULONG Index; + ULONG Count; NTSTATUS status; Frontend = Receiver->Frontend; @@ -2898,7 +2936,10 @@ ReceiverStoreWrite( if (!NT_SUCCESS(status)) goto fail5; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2940,11 +2981,15 @@ ReceiverEnable( { PXENVIF_FRONTEND Frontend; ULONG Index; + ULONG Count; NTSTATUS status; Frontend = Receiver->Frontend; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2961,7 +3006,7 @@ ReceiverEnable( fail1: Error("fail1 (%08x)\n", status); - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2980,8 +3025,12 @@ ReceiverDisable( ) { ULONG Index; + ULONG Count; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Receiver->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -2999,6 +3048,7 @@ ReceiverDisconnect( { PXENVIF_FRONTEND Frontend; ULONG Index; + ULONG Count; Frontend = Receiver->Frontend; @@ -3009,7 +3059,10 @@ ReceiverDisconnect( Receiver->DebugCallback); Receiver->DebugCallback = NULL; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; @@ -3047,7 +3100,7 @@ ReceiverTeardown( Receiver->Rings[Index] = NULL; if (Ring == NULL) - break; + continue; // ensure all rings are destroyed __ReceiverRingTeardown(Ring); } @@ -3089,6 +3142,7 @@ ReceiverSetOffloadOptions( ) { ULONG Index; + ULONG Count; if (Receiver->AllowGsoPackets == 0) { Warning("RECEIVER GSO DISALLOWED\n"); @@ -3096,7 +3150,10 @@ ReceiverSetOffloadOptions( Options.OffloadIpVersion6LargePacket = 0; } - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Receiver->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_RECEIVER_RING Ring; Ring = Receiver->Rings[Index]; diff --git a/src/xenvif/receiver.h b/src/xenvif/receiver.h index f926500..1990ac1 100644 --- a/src/xenvif/receiver.h +++ b/src/xenvif/receiver.h @@ -43,7 +43,6 @@ typedef struct _XENVIF_RECEIVER XENVIF_RECEIVER, *PXENVIF_RECEIVER; extern NTSTATUS ReceiverInitialize( IN PXENVIF_FRONTEND Frontend, - IN ULONG Count, OUT PXENVIF_RECEIVER *Receiver ); diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c index 914e544..445fa8b 100644 --- a/src/xenvif/transmitter.c +++ b/src/xenvif/transmitter.c @@ -103,6 +103,7 @@ typedef struct _XENVIF_TRANSMITTER_STATE { typedef struct _XENVIF_TRANSMITTER_RING { PXENVIF_TRANSMITTER Transmitter; ULONG Index; + PCHAR FrontendPath; PXENBUS_CACHE BufferCache; PXENBUS_CACHE FragmentCache; PXENBUS_RANGE_SET RangeSet; @@ -2861,6 +2862,12 @@ __TransmitterRingInitialize( (*Ring)->Transmitter = Transmitter; (*Ring)->Index = Index; + + (*Ring)->FrontendPath = FrontendFormatPath(Frontend, + Index); + if ((*Ring)->FrontendPath == NULL) + goto fail2; + InitializeListHead(&(*Ring)->Queued); InitializeListHead(&(*Ring)->Completed); KeInitializeSpinLock(&(*Ring)->EvtchnLock); @@ -2868,10 +2875,11 @@ __TransmitterRingInitialize( status = RtlStringCbPrintfA(Name, sizeof (Name), - "%s_transmitter_buffer", - FrontendGetPath(Frontend)); + "%s_%u_transmitter_buffer", + FrontendGetPath(Frontend), + (*Ring)->Index); if (!NT_SUCCESS(status)) - goto fail2; + goto fail3; for (Index = 0; Name[Index] != '\0'; Index++) if (Name[Index] == '/') @@ -2889,14 +2897,15 @@ __TransmitterRingInitialize( *Ring, &(*Ring)->BufferCache); if (!NT_SUCCESS(status)) - goto fail3; + goto fail4; status = RtlStringCbPrintfA(Name, sizeof (Name), - "%s_transmitter_req_id", - FrontendGetPath(Frontend)); + "%s_%u_transmitter_req_id", + FrontendGetPath(Frontend), + (*Ring)->Index); if (!NT_SUCCESS(status)) - goto fail4; + goto fail5; for (Index = 0; Name[Index] != '\0'; Index++) if (Name[Index] == '/') @@ -2907,7 +2916,7 @@ __TransmitterRingInitialize( Name, &(*Ring)->RangeSet); if (!NT_SUCCESS(status)) - goto fail5; + goto fail6; status = XENBUS_RANGE_SET(Put, &Transmitter->RangeSetInterface, @@ -2915,14 +2924,15 @@ __TransmitterRingInitialize( 1, XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID); if (!NT_SUCCESS(status)) - goto fail6; + goto fail7; status = RtlStringCbPrintfA(Name, sizeof (Name), - "%s_transmitter_fragment", - FrontendGetPath(Frontend)); + "%s_%u_transmitter_fragment", + FrontendGetPath(Frontend), + (*Ring)->Index); if (!NT_SUCCESS(status)) - goto fail7; + goto fail8; for (Index = 0; Name[Index] != '\0'; Index++) if (Name[Index] == '/') @@ -2940,66 +2950,73 @@ __TransmitterRingInitialize( (*Ring), &(*Ring)->FragmentCache); if (!NT_SUCCESS(status)) - goto fail8; + goto fail9; status = ThreadCreate(TransmitterRingWatchdog, *Ring, &(*Ring)->WatchdogThread); if (!NT_SUCCESS(status)) - goto fail9; + goto fail10; return STATUS_SUCCESS; -fail9: - Error("fail9\n"); +fail10: + Error("fail10\n"); XENBUS_CACHE(Destroy, &Transmitter->CacheInterface, (*Ring)->FragmentCache); (*Ring)->FragmentCache = NULL; +fail9: + Error("fail9\n"); + fail8: Error("fail8\n"); -fail7: - Error("fail7\n"); - (VOID) XENBUS_RANGE_SET(Get, &Transmitter->RangeSetInterface, (*Ring)->RangeSet, 1, XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID); -fail6: - Error("fail6\n"); +fail7: + Error("fail7\n"); XENBUS_RANGE_SET(Destroy, &Transmitter->RangeSetInterface, (*Ring)->RangeSet); (*Ring)->RangeSet = NULL; +fail6: + Error("fail6\n"); + fail5: Error("fail5\n"); -fail4: - Error("fail4\n"); - XENBUS_CACHE(Destroy, &Transmitter->CacheInterface, (*Ring)->BufferCache); (*Ring)->BufferCache = NULL; +fail4: + Error("fail4\n"); + fail3: Error("fail3\n"); -fail2: - Error("fail2\n"); - RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC)); RtlZeroMemory(&(*Ring)->EvtchnLock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&(*Ring)->Queued, sizeof (LIST_ENTRY)); RtlZeroMemory(&(*Ring)->Completed, sizeof (LIST_ENTRY)); + + ExFreePool((*Ring)->FrontendPath); // 'HTAP' + (*Ring)->FrontendPath = NULL; + +fail2: + Error("fail2\n"); + (*Ring)->Index = 0; (*Ring)->Transmitter = NULL; @@ -3077,6 +3094,16 @@ __TransmitterRingConnect( goto fail4; } + if (FrontendGetQueueCount(Frontend) > 1) { + (VOID) XENBUS_EVTCHN(Bind, + &Transmitter->EvtchnInterface, + Ring->Channel, + Ring->Index); + + KeSetTargetProcessorDpc(&Ring->Dpc, + (CCHAR)Ring->Index); + } + Pending = XENBUS_EVTCHN(Unmask, &Transmitter->EvtchnInterface, Ring->Channel, @@ -3149,15 +3176,20 @@ __TransmitterRingStoreWrite( PXENVIF_TRANSMITTER Transmitter; PXENVIF_FRONTEND Frontend; ULONG Port; + PCHAR Path; NTSTATUS status; Transmitter = Ring->Transmitter; Frontend = Transmitter->Frontend; + Path = (FrontendGetQueueCount(Frontend) == 1) ? + FrontendGetPath(Frontend) : + Ring->FrontendPath; + status = XENBUS_STORE(Printf, &Transmitter->StoreInterface, Transaction, - FrontendGetPath(Frontend), + Path, "tx-ring-ref", "%u", GranterGetReference(FrontendGetGranter(Frontend), @@ -3176,7 +3208,7 @@ __TransmitterRingStoreWrite( status = XENBUS_STORE(Printf, &Transmitter->StoreInterface, Transaction, - FrontendGetPath(Frontend), + Path, "event-channel-tx", "%u", Port); @@ -3404,6 +3436,9 @@ __TransmitterRingTeardown( ASSERT(IsListEmpty(&Ring->Completed)); RtlZeroMemory(&Ring->Completed, sizeof (LIST_ENTRY)); + ExFreePool(Ring->FrontendPath); // 'HTAP' + Ring->FrontendPath = NULL; + Ring->Index = 0; Ring->Transmitter = NULL; @@ -3498,14 +3533,15 @@ TransmitterDebugCallback( NTSTATUS TransmitterInitialize( IN PXENVIF_FRONTEND Frontend, - IN ULONG Count, OUT PXENVIF_TRANSMITTER *Transmitter ) { HANDLE ParametersKey; ULONG Index; + ULONG Count; NTSTATUS status; + Count = DriverGetMaximumQueueCount(); *Transmitter = __TransmitterAllocate(sizeof (XENVIF_TRANSMITTER)); status = STATUS_NO_MEMORY; @@ -3592,7 +3628,7 @@ fail4: (*Transmitter)->Rings[Index] = NULL; if (Ring == NULL) - continue; + continue; // ensure all rings are destroyed __TransmitterRingTeardown(Ring); } @@ -3645,6 +3681,7 @@ TransmitterConnect( PXENVIF_FRONTEND Frontend; PCHAR Buffer; ULONG Index; + ULONG Count; NTSTATUS status; Frontend = Transmitter->Frontend; @@ -3691,7 +3728,10 @@ TransmitterConnect( Buffer); } - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; @@ -3725,7 +3765,7 @@ fail5: Ring = Transmitter->Rings[Index]; if (Ring == NULL) - continue; + continue; // ensure all rings are destroyed __TransmitterRingDisconnect(Ring); } @@ -3763,9 +3803,13 @@ TransmitterStoreWrite( ) { NTSTATUS status; - ULONG Index; + ULONG Index; + ULONG Count; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Transmitter->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; @@ -3791,8 +3835,12 @@ TransmitterEnable( ) { ULONG Index; + ULONG Count; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Transmitter->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; @@ -3811,8 +3859,12 @@ TransmitterDisable( ) { ULONG Index; + ULONG Count; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Transmitter->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; @@ -3830,6 +3882,7 @@ TransmitterDisconnect( { PXENVIF_FRONTEND Frontend; ULONG Index; + ULONG Count; Frontend = Transmitter->Frontend; @@ -3840,7 +3893,10 @@ TransmitterDisconnect( Transmitter->DebugCallback); Transmitter->DebugCallback = NULL; - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; @@ -3882,7 +3938,7 @@ TransmitterTeardown( Transmitter->Rings[Index] = NULL; if (Ring == NULL) - continue; + continue; // ensure all rings are destroyed __TransmitterRingTeardown(Ring); } @@ -4132,20 +4188,66 @@ TransmitterQueuePacketsV1( #undef OFFSET_EXISTS } +static FORCEINLINE ULONG +__GetQueue( + IN ULONG QueueCount, + IN ULONG HashValue + ) +{ + return HashValue % QueueCount; +} + VOID TransmitterQueuePacketsV2( IN PXENVIF_TRANSMITTER Transmitter, IN PLIST_ENTRY List ) { - PXENVIF_TRANSMITTER_RING Ring; + PXENVIF_TRANSMITTER_RING Ring; + PXENVIF_FRONTEND Frontend; + ULONG QueueCount; - // We need to hash for a ring eventually. Since there is only a - // single ring for now, we just use that. - Ring = Transmitter->Rings[0]; - ASSERT3P(Ring, !=, NULL); + Frontend = Transmitter->Frontend; + + QueueCount = FrontendGetQueueCount(Frontend); + + if (QueueCount == 1) { + Ring = Transmitter->Rings[0]; + ASSERT3P(Ring, !=, NULL); - __TransmitterRingQueuePackets(Ring, List); + __TransmitterRingQueuePackets(Ring, List); + } else { + while (!IsListEmpty(List)) { + PXENVIF_TRANSMITTER_PACKET Packet; + PLIST_ENTRY ListEntry; + LIST_ENTRY ListHead; + ULONG Queue; + + InitializeListHead(&ListHead); + + ListEntry = List->Flink; + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, ListEntry); + Queue = __GetQueue(QueueCount, Packet->Value); + + (VOID) RemoveHeadList(List); + InsertTailList(&ListHead, ListEntry); + + while (!IsListEmpty(List)) { + ListEntry = List->Flink; + Packet = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_PACKET, ListEntry); + if (Queue != __GetQueue(QueueCount, Packet->Value)) + break; + + (VOID) RemoveHeadList(List); + InsertTailList(&ListHead, ListEntry); + } + + Ring = Transmitter->Rings[Queue]; + ASSERT3P(Ring, !=, NULL); + + __TransmitterRingQueuePackets(Ring, &ListHead); + } + } } VOID @@ -4154,11 +4256,15 @@ TransmitterAbortPackets( ) { ULONG Index; + ULONG Count; KIRQL Irql; KeRaiseIrql(DISPATCH_LEVEL, &Irql); - for (Index = 0; Index < MAXIMUM_PROCESSORS; ++Index) { + Count = FrontendGetQueueCount(Transmitter->Frontend); + ASSERT3U(Count, <=, MAXIMUM_PROCESSORS); + + for (Index = 0; Index < Count; ++Index) { PXENVIF_TRANSMITTER_RING Ring; Ring = Transmitter->Rings[Index]; diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h index 2ed2786..666f049 100644 --- a/src/xenvif/transmitter.h +++ b/src/xenvif/transmitter.h @@ -43,7 +43,6 @@ typedef struct _XENVIF_TRANSMITTER XENVIF_TRANSMITTER, *PXENVIF_TRANSMITTER; extern NTSTATUS TransmitterInitialize( IN PXENVIF_FRONTEND Frontend, - IN ULONG Count, OUT PXENVIF_TRANSMITTER *Transmitter ); -- 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 |