[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 05/10] Split notifier into a list of queues.
> -----Original Message----- > From: Owen Smith [mailto:owen.smith@xxxxxxxxxx] > Sent: 12 November 2014 16:39 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Paul Durrant; Owen Smith > Subject: [PATCH 05/10] Split notifier into a list of queues. > > Move event channel registration to a list item, with 1 item per > max-queue. > Please get rid of the notifier object. Have the receiver code own the event channel in the non-split case. Have receiver and transmitter own their own in the split case then the move the event channel from the receiver/transmitter struct to the per-ring struct when multi-queue support is added. Paul > 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 |