[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 05/10] Split notifier into a list of queues.
Move event channel registration to a list item, with 1 item per max-queue. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvif/notifier.c | 686 +++++++++++++++++++++++++++++++++-------------- src/xenvif/notifier.h | 12 +- src/xenvif/receiver.c | 11 +- src/xenvif/receiver.h | 3 +- src/xenvif/transmitter.c | 9 +- src/xenvif/transmitter.h | 3 +- 6 files changed, 512 insertions(+), 212 deletions(-) diff --git a/src/xenvif/notifier.c b/src/xenvif/notifier.c index fc6725a..02a11d8 100644 --- a/src/xenvif/notifier.c +++ b/src/xenvif/notifier.c @@ -52,19 +52,26 @@ typedef enum _XENVIF_NOTIFIER_EVTCHN { struct _XENVIF_NOTIFIER { PXENVIF_FRONTEND Frontend; XENBUS_EVTCHN_INTERFACE EvtchnInterface; - PXENBUS_EVTCHN_CHANNEL Channel[XENVIF_NOTIFIER_EVTCHN_COUNT]; - KDPC Dpc[XENVIF_NOTIFIER_EVTCHN_COUNT]; - ULONG Dpcs[XENVIF_NOTIFIER_EVTCHN_COUNT]; - ULONG Events[XENVIF_NOTIFIER_EVTCHN_COUNT]; BOOLEAN Connected; KSPIN_LOCK Lock; BOOLEAN Split; BOOLEAN Enabled; + LIST_ENTRY List; XENBUS_STORE_INTERFACE StoreInterface; XENBUS_DEBUG_INTERFACE DebugInterface; PXENBUS_DEBUG_CALLBACK DebugCallback; }; +typedef struct _XENVIF_NOTIFIER_QUEUE { + PXENVIF_NOTIFIER Notifier; + LIST_ENTRY ListEntry; + ULONG Index; + PXENBUS_EVTCHN_CHANNEL Channel[XENVIF_NOTIFIER_EVTCHN_COUNT]; + KDPC Dpc[XENVIF_NOTIFIER_EVTCHN_COUNT]; + ULONG Dpcs[XENVIF_NOTIFIER_EVTCHN_COUNT]; + ULONG Events[XENVIF_NOTIFIER_EVTCHN_COUNT]; +} XENVIF_NOTIFIER_QUEUE, *PXENVIF_NOTIFIER_QUEUE; + #define XENVIF_NOTIFIER_TAG 'ITON' static FORCEINLINE PVOID @@ -84,22 +91,24 @@ __NotifierFree( } static FORCEINLINE BOOLEAN -__NotifierUnmask( - IN PXENVIF_NOTIFIER Notifier, +__NotifierQueueUnmask( + IN PXENVIF_NOTIFIER_QUEUE Queue, IN XENVIF_NOTIFIER_EVTCHN Index ) { + PXENVIF_NOTIFIER Notifier; PXENVIF_FRONTEND Frontend; BOOLEAN Pending; + Notifier = Queue->Notifier; Frontend = Notifier->Frontend; KeAcquireSpinLockAtDpcLevel(&Notifier->Lock); - Pending = (Notifier->Connected) ? + Pending = (Notifier->Connected && Queue->Channel[Index]) ? XENBUS_EVTCHN(Unmask, &Notifier->EvtchnInterface, - Notifier->Channel[Index], + Queue->Channel[Index], FALSE) : FALSE; @@ -114,14 +123,15 @@ __drv_minIRQL(DISPATCH_LEVEL) __drv_requiresIRQL(DISPATCH_LEVEL) __drv_sameIRQL static VOID -NotifierDpc( +NotifierQueueDpc( IN PKDPC Dpc, IN PVOID Context, IN PVOID Argument1, IN PVOID Argument2 ) { - PXENVIF_NOTIFIER Notifier = Context; + PXENVIF_NOTIFIER_QUEUE Queue = Context; + PXENVIF_NOTIFIER Notifier; XENVIF_NOTIFIER_EVTCHN Index = (ULONG_PTR)Argument1; PXENVIF_FRONTEND Frontend; BOOLEAN Pending; @@ -129,24 +139,25 @@ NotifierDpc( UNREFERENCED_PARAMETER(Dpc); UNREFERENCED_PARAMETER(Argument2); - ASSERT(Notifier != NULL); + ASSERT(Queue != NULL); + Notifier = Queue->Notifier; Frontend = Notifier->Frontend; do { if (Notifier->Enabled) { switch (Index) { case XENVIF_NOTIFIER_EVTCHN_TX: - TransmitterNotify(FrontendGetTransmitter(Frontend)); + TransmitterNotify(FrontendGetTransmitter(Frontend), Queue->Index); break; case XENVIF_NOTIFIER_EVTCHN_RX: - ReceiverNotify(FrontendGetReceiver(Frontend)); + ReceiverNotify(FrontendGetReceiver(Frontend), Queue->Index); break; case XENVIF_NOTIFIER_EVTCHN_COMBINED: - TransmitterNotify(FrontendGetTransmitter(Frontend)); - ReceiverNotify(FrontendGetReceiver(Frontend)); + TransmitterNotify(FrontendGetTransmitter(Frontend), Queue->Index); + ReceiverNotify(FrontendGetReceiver(Frontend), Queue->Index); break; default: @@ -155,88 +166,345 @@ NotifierDpc( } } - Pending = __NotifierUnmask(Notifier, Index); + Pending = __NotifierQueueUnmask(Queue, Index); } while (Pending); } static FORCEINLINE BOOLEAN -__NotifierEvtchnCallback( - IN PXENVIF_NOTIFIER Notifier, - IN XENVIF_NOTIFIER_EVTCHN Index +__NotifierQueueEvtchnCallback( + IN PXENVIF_NOTIFIER_QUEUE Queue, + IN XENVIF_NOTIFIER_EVTCHN Index ) { - Notifier->Events[Index]++; + Queue->Events[Index]++; - if (KeInsertQueueDpc(&Notifier->Dpc[Index], + if (KeInsertQueueDpc(&Queue->Dpc[Index], (PVOID)(ULONG_PTR)Index, NULL)) - Notifier->Dpcs[Index]++; + Queue->Dpcs[Index]++; return TRUE; } -#define DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(_Type) \ +#define DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(_Type) \ \ -KSERVICE_ROUTINE Notifier ## _Type ## EvtchnCallback; \ +KSERVICE_ROUTINE NotifierQueue ## _Type ## EvtchnCallback; \ \ BOOLEAN \ -Notifier ## _Type ## EvtchnCallback( \ +NotifierQueue ## _Type ## EvtchnCallback( \ IN PKINTERRUPT InterruptObject, \ IN PVOID Argument \ ) \ { \ - PXENVIF_NOTIFIER Notifier = Argument; \ + PXENVIF_NOTIFIER_QUEUE Queue = Argument; \ \ UNREFERENCED_PARAMETER(InterruptObject); \ \ - ASSERT(Notifier != NULL); \ - return __NotifierEvtchnCallback(Notifier, \ + ASSERT(Queue != NULL); \ + return __NotifierQueueEvtchnCallback(Queue, \ XENVIF_NOTIFIER_EVTCHN_ ## _Type); \ } -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(COMBINED) -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(RX) -DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(TX) +DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(COMBINED) +DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(RX) +DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(TX) -#undef DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK +#undef DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK -#define DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(_Type) \ - Notifier ## _Type ## EvtchnCallback, +#define DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(_Type) \ + NotifierQueue ## _Type ## EvtchnCallback, -PKSERVICE_ROUTINE NotifierEvtchnCallback[] = { - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(COMBINED) - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(RX) - DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK(TX) +PKSERVICE_ROUTINE NotifierQueueEvtchnCallback[] = { + DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(COMBINED) + DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(RX) + DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK(TX) }; -#undef DEFINE_XENVIF_NOTIFIER_EVTCHN_CALLBACK +#undef DEFINE_XENVIF_NOTIFIER_QUEUE_EVTCHN_CALLBACK -C_ASSERT(ARRAYSIZE(NotifierEvtchnCallback) == XENVIF_NOTIFIER_EVTCHN_COUNT); +C_ASSERT(ARRAYSIZE(NotifierQueueEvtchnCallback) == XENVIF_NOTIFIER_EVTCHN_COUNT); static VOID -NotifierDebugCallback( - IN PVOID Argument, - IN BOOLEAN Crashing +NotifierQueueDebugCallback( + IN PXENVIF_NOTIFIER_QUEUE Queue ) { - PXENVIF_NOTIFIER Notifier = Argument; - PXENVIF_FRONTEND Frontend; + PXENVIF_NOTIFIER Notifier = Queue->Notifier; ULONG Index; - UNREFERENCED_PARAMETER(Crashing); - - Frontend = Notifier->Frontend; - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) XENBUS_DEBUG(Printf, &Notifier->DebugInterface, - "[%s]: Events = %lu Dpcs = %lu\n", + "[%u][%s]: Events = %lu Dpcs = %lu\n", + Queue->Index, ((Index == XENVIF_NOTIFIER_EVTCHN_COMBINED) ? "COMBINED" : ((Index == XENVIF_NOTIFIER_EVTCHN_RX) ? "RX" : ((Index == XENVIF_NOTIFIER_EVTCHN_TX) ? "TX" : "UNKNOWN"))), - Notifier->Events[Index], - Notifier->Dpcs[Index]); + Queue->Events[Index], + Queue->Dpcs[Index]); +} + +static NTSTATUS +NotifierQueueInitialize( + IN PXENVIF_NOTIFIER Notifier, + IN ULONG QueueIndex, + OUT PXENVIF_NOTIFIER_QUEUE *Queue + ) +{ + ULONG Index; + NTSTATUS status; + + *Queue = __NotifierAllocate(sizeof (XENVIF_NOTIFIER_QUEUE)); + + status = STATUS_NO_MEMORY; + if (*Queue == NULL) + goto fail1; + + (*Queue)->Notifier = Notifier; + (*Queue)->Index = QueueIndex; + + for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) + KeInitializeDpc(&(*Queue)->Dpc[Index], + NotifierQueueDpc, + *Queue); + + return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + return status; +} + +static NTSTATUS +NotifierQueueConnect( + IN PXENVIF_NOTIFIER_QUEUE Queue + ) +{ + PXENVIF_NOTIFIER Notifier; + PXENVIF_FRONTEND Frontend; + LONG Index; + NTSTATUS status; + + Notifier = Queue->Notifier; + Frontend = Notifier->Frontend; + + for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { + PKSERVICE_ROUTINE Callback = NotifierQueueEvtchnCallback[Index]; + BOOLEAN Pending; + + Queue->Channel[Index] = XENBUS_EVTCHN(Open, + &Notifier->EvtchnInterface, + XENBUS_EVTCHN_TYPE_UNBOUND, + Callback, + Queue, + FrontendGetBackendDomain(Frontend), + TRUE); + + status = STATUS_UNSUCCESSFUL; + if (Queue->Channel[Index] == NULL) + goto fail1; + + Pending = XENBUS_EVTCHN(Unmask, + &Notifier->EvtchnInterface, + Queue->Channel[Index], + FALSE); + if (Pending) + XENBUS_EVTCHN(Trigger, + &Notifier->EvtchnInterface, + Queue->Channel[Index]); + } + + return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + while (--Index >= 0) { + XENBUS_EVTCHN(Close, + &Notifier->EvtchnInterface, + Queue->Channel[Index]); + Queue->Channel[Index] = NULL; + + Queue->Events[Index] = 0; + } + + return status; +} + +static NTSTATUS +NotifierQueueStoreWrite( + IN PXENVIF_NOTIFIER_QUEUE Queue, + IN PXENBUS_STORE_TRANSACTION Transaction + ) +{ + PXENVIF_NOTIFIER Notifier = Queue->Notifier; + PXENVIF_FRONTEND Frontend = Notifier->Frontend; + ULONG Index; + NTSTATUS status; + + for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { + PCHAR Node; + ULONG Port; + + switch (Index) { + case XENVIF_NOTIFIER_EVTCHN_COMBINED: + if (Notifier->Split) + continue; + + Node = "event-channel"; + break; + + case XENVIF_NOTIFIER_EVTCHN_RX: + if (!Notifier->Split) + continue; + + Node = "event-channel-rx"; + break; + + case XENVIF_NOTIFIER_EVTCHN_TX: + if (!Notifier->Split) + continue; + + Node = "event-channel-tx"; + break; + + default: + ASSERT(FALSE); + + Node = ""; + break; + } + + Port = XENBUS_EVTCHN(GetPort, + &Notifier->EvtchnInterface, + Queue->Channel[Index]); + + status = XENBUS_STORE(Printf, + &Notifier->StoreInterface, + Transaction, + FrontendGetPath(Frontend), + Node, + "%u", + Port); + + if (!NT_SUCCESS(status)) + goto fail1; + } + + return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +static NTSTATUS +NotifierQueueEnable( + IN PXENVIF_NOTIFIER_QUEUE Queue + ) +{ + PXENVIF_NOTIFIER Notifier = Queue->Notifier; + ULONG Index; + + for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { + switch (Index) { + case XENVIF_NOTIFIER_EVTCHN_COMBINED: + if (Notifier->Split) + continue; + + break; + + case XENVIF_NOTIFIER_EVTCHN_RX: + if (!Notifier->Split) + continue; + + break; + + case XENVIF_NOTIFIER_EVTCHN_TX: + if (!Notifier->Split) + continue; + + break; + + default: + ASSERT(FALSE); + + break; + } + + if (KeInsertQueueDpc(&Queue->Dpc[Index], + (PVOID)(ULONG_PTR)Index, + NULL)) + Queue->Dpcs[Index]++; + } + + return STATUS_SUCCESS; +} + +static VOID +NotifierQueueDisconnect( + IN PXENVIF_NOTIFIER_QUEUE Queue + ) +{ + PXENVIF_NOTIFIER Notifier = Queue->Notifier; + LONG Index; + + Index = XENVIF_NOTIFIER_EVTCHN_COUNT; + while (--Index >= 0) { + if (Queue->Channel[Index] == NULL) + continue; + + XENBUS_EVTCHN(Close, + &Notifier->EvtchnInterface, + Queue->Channel[Index]); + Queue->Channel[Index] = NULL; + + Queue->Events[Index] = 0; + } +} + +static VOID +NotifierQueueTeardown( + IN PXENVIF_NOTIFIER_QUEUE Queue + ) +{ + LONG Index; + + Index = XENVIF_NOTIFIER_EVTCHN_COUNT; + while (--Index >= 0) { + Queue->Dpcs[Index] = 0; + RtlZeroMemory(&Queue->Dpc[Index], sizeof (KDPC)); + } + + Queue->Notifier = NULL; + Queue->Index = 0; + + ASSERT(IsZeroMemory(Queue, sizeof (XENVIF_NOTIFIER_QUEUE))); + + __NotifierFree(Queue); +} + +static VOID +NotifierDebugCallback( + IN PVOID Argument, + IN BOOLEAN Crashing + ) +{ + PXENVIF_NOTIFIER Notifier = Argument; + PLIST_ENTRY ListEntry; + + UNREFERENCED_PARAMETER(Crashing); + + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + NotifierQueueDebugCallback(Queue); + } } NTSTATUS @@ -266,13 +534,41 @@ NotifierInitialize( (*Notifier)->Frontend = Frontend; KeInitializeSpinLock(&(*Notifier)->Lock); - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) - KeInitializeDpc(&(*Notifier)->Dpc[Index], - NotifierDpc, - *Notifier); + InitializeListHead(&(*Notifier)->List); + + Index = 0; + while (Index < DriverGetQueueMax()) { + PXENVIF_NOTIFIER_QUEUE Queue; + + status = NotifierQueueInitialize(*Notifier, Index, &Queue); + if (!NT_SUCCESS(status)) + goto fail2; + + InsertTailList(&(*Notifier)->List, &Queue->ListEntry); + Index++; + } return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + + while (!IsListEmpty(&(*Notifier)->List)) { + PLIST_ENTRY ListEntry; + PXENVIF_NOTIFIER_QUEUE Queue; + + ListEntry = RemoveTailList(&(*Notifier)->List); + ASSERT3P(ListEntry, !=, &(*Notifier)->List); + + RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY)); + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + + NotifierQueueTeardown(Queue); + --Index; + } + ASSERT3U(Index, ==, 0); + fail1: Error("fail1 (%08x)\n", status); @@ -285,7 +581,7 @@ NotifierConnect( ) { PXENVIF_FRONTEND Frontend; - LONG Index; + PLIST_ENTRY ListEntry; PCHAR Buffer; NTSTATUS status; @@ -308,32 +604,6 @@ NotifierConnect( if (!NT_SUCCESS(status)) goto fail3; - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - PKSERVICE_ROUTINE Callback = NotifierEvtchnCallback[Index]; - BOOLEAN Pending; - - Notifier->Channel[Index] = XENBUS_EVTCHN(Open, - &Notifier->EvtchnInterface, - XENBUS_EVTCHN_TYPE_UNBOUND, - Callback, - Notifier, - FrontendGetBackendDomain(Frontend), - TRUE); - - status = STATUS_UNSUCCESSFUL; - if (Notifier->Channel[Index] == NULL) - goto fail4; - - Pending = XENBUS_EVTCHN(Unmask, - &Notifier->EvtchnInterface, - Notifier->Channel[Index], - FALSE); - if (Pending) - XENBUS_EVTCHN(Trigger, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - } - status = XENBUS_DEBUG(Register, &Notifier->DebugInterface, __MODULE__ "|NOTIFIER", @@ -341,7 +611,7 @@ NotifierConnect( Notifier, &Notifier->DebugCallback); if (!NT_SUCCESS(status)) - goto fail5; + goto fail4; status = XENBUS_STORE(Read, &Notifier->StoreInterface, @@ -359,6 +629,20 @@ NotifierConnect( Buffer); } + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index >= FrontendGetQueueCount(Frontend)) + continue; + + status = NotifierQueueConnect(Queue); + if (!NT_SUCCESS(status)) + goto fail5; + } + Notifier->Connected = TRUE; KeReleaseSpinLockFromDpcLevel(&Notifier->Lock); @@ -367,20 +651,19 @@ NotifierConnect( fail5: Error("fail5\n"); - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; -fail4: - Error("fail4\n"); - - while (--Index >= 0) { - XENBUS_EVTCHN(Close, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - Notifier->Channel[Index] = NULL; + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); - Notifier->Events[Index] = 0; + NotifierQueueDisconnect(Queue); } +fail4: + Error("fail4\n"); + XENBUS_STORE(Release, &Notifier->StoreInterface); fail3: @@ -408,54 +691,20 @@ NotifierStoreWrite( ) { PXENVIF_FRONTEND Frontend = Notifier->Frontend; - ULONG Index; + PLIST_ENTRY ListEntry; NTSTATUS status; - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - PCHAR Node; - ULONG Port; - - switch (Index) { - case XENVIF_NOTIFIER_EVTCHN_COMBINED: - if (Notifier->Split) - continue; - - Node = "event-channel"; - break; - - case XENVIF_NOTIFIER_EVTCHN_RX: - if (!Notifier->Split) - continue; - - Node = "event-channel-rx"; - break; - - case XENVIF_NOTIFIER_EVTCHN_TX: - if (!Notifier->Split) - continue; - - Node = "event-channel-tx"; - break; - - default: - ASSERT(FALSE); + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; - Node = ""; - break; - } - - Port = XENBUS_EVTCHN(GetPort, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - - status = XENBUS_STORE(Printf, - &Notifier->StoreInterface, - Transaction, - FrontendGetPath(Frontend), - Node, - "%u", - Port); + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index > FrontendGetQueueCount(Frontend)) + continue; + status = NotifierQueueStoreWrite(Queue, + Transaction); if (!NT_SUCCESS(status)) goto fail1; } @@ -473,44 +722,34 @@ NotifierEnable( IN PXENVIF_NOTIFIER Notifier ) { - ULONG Index; + PLIST_ENTRY ListEntry; + PXENVIF_FRONTEND Frontend; + NTSTATUS status; + + Frontend = Notifier->Frontend; ASSERT(!Notifier->Enabled); Notifier->Enabled = TRUE; - for (Index = 0; Index < XENVIF_NOTIFIER_EVTCHN_COUNT; Index++) { - switch (Index) { - case XENVIF_NOTIFIER_EVTCHN_COMBINED: - if (Notifier->Split) - continue; - - break; - - case XENVIF_NOTIFIER_EVTCHN_RX: - if (!Notifier->Split) - continue; - - break; - - case XENVIF_NOTIFIER_EVTCHN_TX: - if (!Notifier->Split) - continue; - - break; - - default: - ASSERT(FALSE); + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; - break; - } + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index > FrontendGetQueueCount(Frontend)) + continue; - if (KeInsertQueueDpc(&Notifier->Dpc[Index], - (PVOID)(ULONG_PTR)Index, - NULL)) - Notifier->Dpcs[Index]++; + status = NotifierQueueEnable(Queue); + if (!NT_SUCCESS(status)) + goto fail1; } return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + return status; } VOID @@ -528,7 +767,7 @@ NotifierDisconnect( ) { PXENVIF_FRONTEND Frontend; - LONG Index; + PLIST_ENTRY ListEntry; Frontend = Notifier->Frontend; @@ -544,14 +783,16 @@ NotifierDisconnect( Notifier->DebugCallback); Notifier->DebugCallback = NULL; - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; - while (--Index >= 0) { - XENBUS_EVTCHN(Close, - &Notifier->EvtchnInterface, - Notifier->Channel[Index]); - Notifier->Channel[Index] = NULL; + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; - Notifier->Events[Index] = 0; + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index >= FrontendGetQueueCount(Frontend)) + continue; + + NotifierQueueDisconnect(Queue); } XENBUS_STORE(Release, &Notifier->StoreInterface); @@ -568,15 +809,21 @@ NotifierTeardown( IN PXENVIF_NOTIFIER Notifier ) { - LONG Index; - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); KeFlushQueuedDpcs(); - Index = XENVIF_NOTIFIER_EVTCHN_COUNT; - while (--Index >= 0) { - Notifier->Dpcs[Index] = 0; - RtlZeroMemory(&Notifier->Dpc[Index], sizeof (KDPC)); + while (!IsListEmpty(&Notifier->List)) { + PLIST_ENTRY ListEntry; + PXENVIF_NOTIFIER_QUEUE Queue; + + ListEntry = RemoveTailList(&Notifier->List); + ASSERT3P(ListEntry, !=, &Notifier->List); + + RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY)); + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + + NotifierQueueTeardown(Queue); } Notifier->Frontend = NULL; @@ -590,6 +837,7 @@ NotifierTeardown( RtlZeroMemory(&Notifier->EvtchnInterface, sizeof (XENBUS_EVTCHN_INTERFACE)); + RtlZeroMemory(&Notifier->List, sizeof(LIST_ENTRY)); RtlZeroMemory(&Notifier->Lock, sizeof (KSPIN_LOCK)); ASSERT(IsZeroMemory(Notifier, sizeof (XENVIF_NOTIFIER))); @@ -600,85 +848,125 @@ NotifierTeardown( static FORCEINLINE VOID __NotifierSend( IN PXENVIF_NOTIFIER Notifier, - IN ULONG Index + IN ULONG Index, + IN ULONG QueueIndex ) { PXENVIF_FRONTEND Frontend; + PLIST_ENTRY ListEntry; KIRQL Irql; Frontend = Notifier->Frontend; KeAcquireSpinLock(&Notifier->Lock, &Irql); - if (Notifier->Connected) + if (!Notifier->Connected) + goto done; + + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index >= FrontendGetQueueCount(Frontend)) + continue; + if (Queue->Index != QueueIndex) + continue; + (VOID) XENBUS_EVTCHN(Send, &Notifier->EvtchnInterface, - Notifier->Channel[Index]); + Queue->Channel[Index]); + break; + } +done: KeReleaseSpinLock(&Notifier->Lock, Irql); } VOID NotifierSendTx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ) { if (Notifier->Split) - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_TX); + __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_TX, Queue); else - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); + __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED, Queue); } VOID NotifierSendRx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ) { if (Notifier->Split) - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_RX); + __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_RX, Queue); else - __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); + __NotifierSend(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED, Queue); } static FORCEINLINE VOID __NotifierTrigger( IN PXENVIF_NOTIFIER Notifier, - IN ULONG Index + IN ULONG Index, + IN ULONG QueueIndex ) { PXENVIF_FRONTEND Frontend; + PLIST_ENTRY ListEntry; KIRQL Irql; Frontend = Notifier->Frontend; KeAcquireSpinLock(&Notifier->Lock, &Irql); - if (Notifier->Connected) + if (!Notifier->Connected) + goto done; + + for (ListEntry = Notifier->List.Flink; + ListEntry != &Notifier->List; + ListEntry = ListEntry->Flink) { + PXENVIF_NOTIFIER_QUEUE Queue; + + Queue = CONTAINING_RECORD(ListEntry, XENVIF_NOTIFIER_QUEUE, ListEntry); + if (Queue->Index >= FrontendGetQueueCount(Frontend)) + continue; + if (Queue->Index != QueueIndex) + continue; + (VOID) XENBUS_EVTCHN(Trigger, &Notifier->EvtchnInterface, - Notifier->Channel[Index]); + Queue->Channel[Index]); + break; + } +done: KeReleaseSpinLock(&Notifier->Lock, Irql); } VOID NotifierTriggerTx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ) { if (Notifier->Split) - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_TX); + __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_TX, Queue); else - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); + __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED, Queue); } VOID NotifierTriggerRx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ) { if (Notifier->Split) - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_RX); + __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_RX, Queue); else - __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED); + __NotifierTrigger(Notifier, XENVIF_NOTIFIER_EVTCHN_COMBINED, Queue); } diff --git a/src/xenvif/notifier.h b/src/xenvif/notifier.h index 2f06a6f..fd28060 100644 --- a/src/xenvif/notifier.h +++ b/src/xenvif/notifier.h @@ -78,22 +78,26 @@ NotifierTeardown( extern VOID NotifierSendTx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ); extern VOID NotifierSendRx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ); extern VOID NotifierTriggerTx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ); extern VOID NotifierTriggerRx( - IN PXENVIF_NOTIFIER Notifier + IN PXENVIF_NOTIFIER Notifier, + IN ULONG Queue ); #endif // _XENVIF_NOTIFIER_H diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c index 626feed..85ebcf9 100644 --- a/src/xenvif/receiver.c +++ b/src/xenvif/receiver.c @@ -1397,7 +1397,7 @@ __ReceiverRingReturnPacket( Receiver = Ring->Receiver; Frontend = Receiver->Frontend; - NotifierTriggerRx(FrontendGetNotifier(Frontend)); + NotifierTriggerRx(FrontendGetNotifier(Frontend), Ring->Index); } if (!Locked) @@ -1477,7 +1477,7 @@ __ReceiverRingPushRequests( Receiver = Ring->Receiver; Frontend = Receiver->Frontend; - NotifierSendRx(FrontendGetNotifier(Frontend)); + NotifierSendRx(FrontendGetNotifier(Frontend), Ring->Index); } Ring->RequestsPushed = Ring->RequestsPosted; @@ -1869,7 +1869,7 @@ ReceiverRingWatchdog( // Try to move things along ReceiverRingPoll(Ring); - NotifierSendRx(FrontendGetNotifier(Frontend)); + NotifierSendRx(FrontendGetNotifier(Frontend), Ring->Index); } KeMemoryBarrier(); @@ -2941,7 +2941,8 @@ ReceiverWaitForPackets( VOID ReceiverNotify( - IN PXENVIF_RECEIVER Receiver + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index ) { PLIST_ENTRY ListEntry; @@ -2952,6 +2953,8 @@ ReceiverNotify( PXENVIF_RECEIVER_RING Ring; Ring = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_RING, ListEntry); + if (Ring->Index != Index) + continue; __ReceiverRingNotify(Ring); } diff --git a/src/xenvif/receiver.h b/src/xenvif/receiver.h index 8009858..1505887 100644 --- a/src/xenvif/receiver.h +++ b/src/xenvif/receiver.h @@ -79,7 +79,8 @@ ReceiverTeardown( extern VOID ReceiverNotify( - IN PXENVIF_RECEIVER Receiver + IN PXENVIF_RECEIVER Receiver, + IN ULONG Index ); extern VOID diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c index bea46f1..477fecc 100644 --- a/src/xenvif/transmitter.c +++ b/src/xenvif/transmitter.c @@ -2195,7 +2195,7 @@ __TransmitterRingPushRequests( Transmitter = Ring->Transmitter; Frontend = Transmitter->Frontend; - NotifierSendTx(FrontendGetNotifier(Frontend)); + NotifierSendTx(FrontendGetNotifier(Frontend), Ring->Index); } Ring->RequestsPushed = Ring->RequestsPosted; @@ -2624,7 +2624,7 @@ TransmitterRingWatchdog( Ring->DebugCallback); // Try to move things along - NotifierSendTx(FrontendGetNotifier(Frontend)); + NotifierSendTx(FrontendGetNotifier(Frontend), Ring->Index); TransmitterRingPoll(Ring); } @@ -3972,7 +3972,8 @@ TransmitterQueryRingSize( VOID TransmitterNotify( - IN PXENVIF_TRANSMITTER Transmitter + IN PXENVIF_TRANSMITTER Transmitter, + IN ULONG Index ) { PLIST_ENTRY ListEntry; @@ -3983,6 +3984,8 @@ TransmitterNotify( PXENVIF_TRANSMITTER_RING Ring; Ring = CONTAINING_RECORD(ListEntry, XENVIF_TRANSMITTER_RING, ListEntry); + if (Ring->Index != Index) + continue; __TransmitterRingNotify(Ring); } diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h index 7e10603..3e56b34 100644 --- a/src/xenvif/transmitter.h +++ b/src/xenvif/transmitter.h @@ -79,7 +79,8 @@ TransmitterTeardown( extern VOID TransmitterNotify( - IN PXENVIF_TRANSMITTER Transmitter + IN PXENVIF_TRANSMITTER Transmitter, + IN ULONG Index ); extern VOID -- 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 |