[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.