|
[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 |