]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Remove use of KeNumberProcessors from EVTCHN code
authorPaul Durrant <paul.durrant@citrix.com>
Wed, 28 Jan 2015 16:27:36 +0000 (16:27 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 29 Jan 2015 14:03:18 +0000 (14:03 +0000)
The crucial things are the virtual CPUs to which the ABI can steer
interrupts and the number of interrupts which the FDO code successfully
allocated. By using an intersection of these two things we can drop any
use of KeNumberProcessors.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenbus/evtchn.c
src/xenbus/evtchn_2l.c
src/xenbus/evtchn_abi.h
src/xenbus/evtchn_fifo.c
src/xenbus/fdo.c
src/xenbus/fdo.h

index 3360a295d969890466f43235cf1cde98dd8dd79e..63af0797b7cd7aa7332450b9bb187a0b9096411c 100644 (file)
@@ -646,13 +646,9 @@ EvtchnBind(
 
     ASSERT3U(Channel->Magic, ==, XENBUS_EVTCHN_CHANNEL_MAGIC);
 
-    status = STATUS_INVALID_PARAMETER;
-    if (Cpu >= (ULONG)KeNumberProcessors)
-        goto fail1;
-
     status = STATUS_NOT_SUPPORTED;
     if (~Context->Affinity & ((KAFFINITY)1 << Cpu))
-        goto fail2;
+        goto fail1;
 
     KeAcquireSpinLock(&Channel->Lock, &Irql);
 
@@ -667,7 +663,7 @@ EvtchnBind(
 
     status = EventChannelBindVirtualCpu(LocalPort, vcpu_id);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     Channel->Cpu = Cpu;
 
@@ -678,14 +674,11 @@ done:
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
-    KeReleaseSpinLock(&Channel->Lock, Irql);
-
 fail2:
     Error("fail2\n");
 
+    KeReleaseSpinLock(&Channel->Lock, Irql);
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -860,7 +853,8 @@ EvtchnInterruptCallback(
 
 static NTSTATUS
 EvtchnAbiAcquire(
-    IN  PXENBUS_EVTCHN_CONTEXT  Context
+    IN  PXENBUS_EVTCHN_CONTEXT  Context,
+    OUT PKAFFINITY              Affinity
     )
 {
     NTSTATUS                    status;
@@ -869,7 +863,9 @@ EvtchnAbiAcquire(
         EvtchnFifoGetAbi(Context->EvtchnFifoContext,
                          &Context->EvtchnAbi);
 
-        status = XENBUS_EVTCHN_ABI(Acquire, &Context->EvtchnAbi);
+        status = XENBUS_EVTCHN_ABI(Acquire,
+                                   &Context->EvtchnAbi,
+                                   Affinity);
         if (!NT_SUCCESS(status))
             goto use_two_level;
 
@@ -881,7 +877,9 @@ use_two_level:
     EvtchnTwoLevelGetAbi(Context->EvtchnTwoLevelContext,
                          &Context->EvtchnAbi);
 
-    status = XENBUS_EVTCHN_ABI(Acquire, &Context->EvtchnAbi);
+    status = XENBUS_EVTCHN_ABI(Acquire,
+                               &Context->EvtchnAbi,
+                               Affinity);
     if (!NT_SUCCESS(status))
         goto fail1;
 
@@ -917,13 +915,13 @@ EvtchnInterruptEnable(
 
     Trace("====>\n");
 
-    ASSERT3U(Context->Affinity, ==, 0);
-
-    Cpu = 0;
-    while (Cpu < KeNumberProcessors) {
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
         unsigned int    vcpu_id;
         UCHAR           Vector;
 
+        if (Context->LatchedInterrupt[Cpu] == NULL)
+            continue;
+
         vcpu_id = SystemVirtualCpuIndex(Cpu);
         Vector = FdoGetInterruptVector(Context->Fdo,
                                        Context->LatchedInterrupt[Cpu]);
@@ -933,8 +931,6 @@ EvtchnInterruptEnable(
             Info("CPU %u\n", Cpu);
             Context->Affinity |= (KAFFINITY)1 << Cpu;
         }
-
-        Cpu++;
     }
 
     Line = FdoGetInterruptLine(Context->Fdo,
@@ -951,7 +947,7 @@ EvtchnInterruptDisable(
     IN  PXENBUS_EVTCHN_CONTEXT  Context
     )
 {
-    LONG                        Cpu;
+    ULONG                       Cpu;
     NTSTATUS                    status;
 
     UNREFERENCED_PARAMETER(Context);
@@ -961,10 +957,12 @@ EvtchnInterruptDisable(
     status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, 0);
     ASSERT(NT_SUCCESS(status));
 
-    Cpu = KeNumberProcessors;
-    while (--Cpu >= 0) {
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
         unsigned int    vcpu_id;
 
+        if (~Context->Affinity & (KAFFINITY)1 << Cpu)
+            continue;
+
         vcpu_id = SystemVirtualCpuIndex(Cpu);
 
         (VOID) HvmSetEvtchnUpcallVector(vcpu_id, 0);
@@ -1011,13 +1009,17 @@ EvtchnSuspendCallbackLate(
     )
 {
     PXENBUS_EVTCHN_CONTEXT  Context = Argument;
+    KAFFINITY               Affinity;
     NTSTATUS                status;
 
     EvtchnAbiRelease(Context);
 
-    status = EvtchnAbiAcquire(Context);
+    status = EvtchnAbiAcquire(Context, &Affinity);
     ASSERT(NT_SUCCESS(status));
 
+    // Affinity must be a superset of Context->Affinity
+    ASSERT3U(Affinity & Context->Affinity, ==, Context->Affinity);
+
     EvtchnInterruptDisable(Context);
     EvtchnInterruptEnable(Context);
 }
@@ -1115,7 +1117,8 @@ EvtchnAcquire(
     PXENBUS_EVTCHN_CONTEXT  Context = Interface->Context;
     PXENBUS_FDO             Fdo = Context->Fdo;
     KIRQL                   Irql;
-    LONG                    Cpu;
+    ULONG                   Cpu;
+    KAFFINITY               Affinity;
     NTSTATUS                status;
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
@@ -1164,31 +1167,29 @@ EvtchnAcquire(
     if (!NT_SUCCESS(status))
         goto fail6;
 
-    status = EvtchnAbiAcquire(Context);
+    status = EvtchnAbiAcquire(Context, &Affinity);
     if (!NT_SUCCESS(status))
         goto fail7;
 
-    status = FdoAllocateInterrupt(Fdo,
-                                  LevelSensitive,
-                                  0,
-                                  EvtchnInterruptCallback,
-                                  Context,
-                                  &Context->LevelSensitiveInterrupt);
-    if (!NT_SUCCESS(status))
-        goto fail8;
+    Context->LevelSensitiveInterrupt = FdoAllocateInterrupt(Fdo,
+                                                            LevelSensitive,
+                                                            0,
+                                                            EvtchnInterruptCallback,
+                                                            Context);
 
-    Cpu = 0;
-    while (Cpu < KeNumberProcessors) {
-        status = FdoAllocateInterrupt(Fdo,
-                                      Latched,
-                                      Cpu,
-                                      EvtchnInterruptCallback,
-                                      Context,
-                                      &Context->LatchedInterrupt[Cpu]);
-        if (!NT_SUCCESS(status))
-            goto fail9;
+    status = STATUS_UNSUCCESSFUL;
+    if (Context->LevelSensitiveInterrupt == NULL)
+        goto fail8;
 
-        Cpu++;
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
+        if (~Affinity & (KAFFINITY)1 << Cpu)
+            continue;
+
+        Context->LatchedInterrupt[Cpu] = FdoAllocateInterrupt(Fdo,
+                                                              Latched,
+                                                              Cpu,
+                                                              EvtchnInterruptCallback,
+                                                              Context);
     }
 
     EvtchnInterruptEnable(Context);
@@ -1200,17 +1201,6 @@ done:
 
     return STATUS_SUCCESS;
 
-fail9:
-    Error("fail9\n");
-
-    while (--Cpu >= 0) {
-        FdoFreeInterrupt(Fdo, Context->LatchedInterrupt[Cpu]);
-        Context->LatchedInterrupt[Cpu] = NULL;
-    }
-
-    FdoFreeInterrupt(Fdo, Context->LevelSensitiveInterrupt);
-    Context->LevelSensitiveInterrupt = NULL;
-
 fail8:
     Error("fail8\n");
 
@@ -1273,7 +1263,7 @@ EvtchnRelease(
     PXENBUS_EVTCHN_CONTEXT  Context = Interface->Context;
     PXENBUS_FDO             Fdo = Context->Fdo;
     KIRQL                   Irql;
-    LONG                    Cpu;
+    ULONG                   Cpu;
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
 
@@ -1284,8 +1274,10 @@ EvtchnRelease(
 
     EvtchnInterruptDisable(Context);
 
-    Cpu = KeNumberProcessors;
-    while (--Cpu >= 0) {
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
+        if (Context->LatchedInterrupt[Cpu] == NULL)
+            continue;
+
         EvtchnFlush(Context, Cpu);
 
         FdoFreeInterrupt(Fdo, Context->LatchedInterrupt[Cpu]);
index 0f839ee75760146e1a2307e7c4039d76ac619e6a..e5af9dba12a7ab917a1a84844df011caf3b86aec 100644 (file)
@@ -148,7 +148,8 @@ EvtchnTwoLevelPortUnmask(
 
 static NTSTATUS
 EvtchnTwoLevelAcquire(
-    IN  PXENBUS_EVTCHN_ABI_CONTEXT      _Context
+    IN  PXENBUS_EVTCHN_ABI_CONTEXT      _Context,
+    OUT PKAFFINITY                      Affinity
     )
 {
     PXENBUS_EVTCHN_TWO_LEVEL_CONTEXT    Context = (PVOID)_Context;
@@ -166,6 +167,8 @@ EvtchnTwoLevelAcquire(
     if (!NT_SUCCESS(status))
         goto fail1;
 
+    *Affinity = (KAFFINITY)1;
+
     Trace("<====\n");
 
 done:
index 237ce7d3254a7cf1a08ba5e4c077bc16c316c5ea..2e1bf4309bb30ac09c2f491c6acecbeba27cce15 100644 (file)
@@ -39,7 +39,8 @@ typedef PVOID *PXENBUS_EVTCHN_ABI_CONTEXT;
 
 typedef NTSTATUS
 (*XENBUS_EVTCHN_ABI_ACQUIRE)(
-    IN  PXENBUS_EVTCHN_ABI_CONTEXT  Context
+    IN  PXENBUS_EVTCHN_ABI_CONTEXT  Context,
+    OUT PKAFFINITY                  Affinity
     );
 
 typedef VOID
index 078e06712b94f32e556a1cd4bb28680798ac2d86..ef72fdbde79d6f231d6d01473460d16881899534 100644 (file)
@@ -494,7 +494,8 @@ EvtchnFifoReset(
 
 static NTSTATUS
 EvtchnFifoAcquire(
-    IN  PXENBUS_EVTCHN_ABI_CONTEXT  _Context
+    IN  PXENBUS_EVTCHN_ABI_CONTEXT  _Context,
+    OUT PKAFFINITY                  Affinity
     )
 {
     PXENBUS_EVTCHN_FIFO_CONTEXT     Context = (PVOID)_Context;
@@ -510,8 +511,10 @@ EvtchnFifoAcquire(
 
     Trace("====>\n");
 
+    *Affinity = 0;
     Cpu = 0;
-    while (Cpu < KeNumberProcessors) {
+
+    while (Cpu < (LONG)KeQueryActiveProcessorCount(NULL)) {
         unsigned int        vcpu_id;
         PFN_NUMBER          Pfn;
         PHYSICAL_ADDRESS    Address;
@@ -538,6 +541,8 @@ EvtchnFifoAcquire(
                   Address.LowPart);
 
         Context->ControlBlockMdl[vcpu_id] = Mdl;
+
+        *Affinity |= (KAFFINITY)1 << Cpu;
         Cpu++;
     }
 
@@ -581,7 +586,7 @@ EvtchnFifoRelease(
 {
     PXENBUS_EVTCHN_FIFO_CONTEXT     Context = (PVOID)_Context;
     KIRQL                           Irql;
-    LONG                            Cpu;
+    int                             vcpu_id;
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
 
@@ -594,14 +599,14 @@ EvtchnFifoRelease(
 
     EvtchnFifoContract(Context);
 
-    Cpu = KeNumberProcessors;
-    while (--Cpu >= 0) {
-        unsigned int    vcpu_id;
+    vcpu_id = MAX_HVM_VCPUS;
+    while (--vcpu_id >= 0) {
         PMDL            Mdl;
 
-        vcpu_id = SystemVirtualCpuIndex(Cpu);
-
         Mdl = Context->ControlBlockMdl[vcpu_id];
+        if (Mdl == NULL)
+            continue;
+
         Context->ControlBlockMdl[vcpu_id] = NULL;
 
         __FreePage(Mdl);
index 7115d8e249d100244a4691720bce74448ca27772..2877923ac902b38856513bcadd291fa88284d876 100644 (file)
@@ -1475,6 +1475,7 @@ FdoFilterResourceRequirements(
     IO_RESOURCE_DESCRIPTOR          Interrupt;
     PIO_RESOURCE_LIST               List;
     ULONG                           Index;
+    ULONG                           Count;
     NTSTATUS                        status;
 
     status = FdoForwardIrpSynchronously(Fdo, Irp);
@@ -1487,8 +1488,10 @@ FdoFilterResourceRequirements(
     Old = (PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information;
     ASSERT3U(Old->AlternativeLists, ==, 1);
 
+    Count = KeQueryActiveProcessorCount(NULL);
+
     Size = Old->ListSize +
-        (sizeof (IO_RESOURCE_DESCRIPTOR) * KeNumberProcessors);
+        (sizeof (IO_RESOURCE_DESCRIPTOR) * Count);
 
     New = __AllocatePoolWithTag(PagedPool, Size, 'SUB');
 
@@ -1525,7 +1528,7 @@ FdoFilterResourceRequirements(
     Interrupt.u.Interrupt.AffinityPolicy = IrqPolicySpecifiedProcessors;
     Interrupt.u.Interrupt.PriorityPolicy = IrqPriorityUndefined;
 
-    for (Index = 0; Index < (ULONG)KeNumberProcessors; Index++) {
+    for (Index = 0; Index < Count; Index++) {
         Interrupt.u.Interrupt.TargetedProcessors = (KAFFINITY)1 << Index;
         List->Descriptors[List->Count++] = Interrupt;
     }
@@ -1879,48 +1882,42 @@ fail1:
     return status;
 }
 
-NTSTATUS
+PXENBUS_INTERRUPT
 FdoAllocateInterrupt(
     IN  PXENBUS_FDO         Fdo,
     IN  KINTERRUPT_MODE     InterruptMode,
     IN  ULONG               Cpu,
     IN  KSERVICE_ROUTINE    Callback,
-    IN  PVOID               Argument OPTIONAL,
-    OUT PXENBUS_INTERRUPT   *Interrupt
+    IN  PVOID               Argument OPTIONAL
     )
 {
     PLIST_ENTRY             ListEntry;
+    PXENBUS_INTERRUPT       Interrupt;
     KIRQL                   Irql;
-    NTSTATUS                status;
 
     for (ListEntry = Fdo->List.Flink;
          ListEntry != &Fdo->List;
          ListEntry = ListEntry->Flink) {
-        *Interrupt = CONTAINING_RECORD(ListEntry, XENBUS_INTERRUPT, ListEntry);
+        Interrupt = CONTAINING_RECORD(ListEntry, XENBUS_INTERRUPT, ListEntry);
 
-        if ((*Interrupt)->Callback == NULL &&
-            (*Interrupt)->InterruptMode == InterruptMode &&
-            (*Interrupt)->Cpu == Cpu)
+        if (Interrupt->Callback == NULL &&
+            Interrupt->InterruptMode == InterruptMode &&
+            Interrupt->Cpu == Cpu)
             goto found;
     }
 
-    *Interrupt = NULL;
-
-    status = STATUS_OBJECT_NAME_NOT_FOUND;
     goto fail1;
 
 found:
-    Irql = FdoAcquireInterruptLock(Fdo, *Interrupt);
-    (*Interrupt)->Callback = Callback;
-    (*Interrupt)->Argument = Argument;
-    FdoReleaseInterruptLock(Fdo, *Interrupt, Irql);
+    Irql = FdoAcquireInterruptLock(Fdo, Interrupt);
+    Interrupt->Callback = Callback;
+    Interrupt->Argument = Argument;
+    FdoReleaseInterruptLock(Fdo, Interrupt, Irql);
 
-    return STATUS_SUCCESS;
+    return Interrupt;
 
 fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
+    return NULL;
 }
 
 UCHAR
index 4916be4de3ca595c1698c16121b9a57b641257a1..a07b55fbd1ee0b7f77ff480f9f945efda5e838c2 100644 (file)
@@ -165,14 +165,13 @@ FdoReleaseInterruptLock(
     IN  __drv_restoresIRQL KIRQL    Irql
     );
 
-extern NTSTATUS
+extern PXENBUS_INTERRUPT
 FdoAllocateInterrupt(
     IN  PXENBUS_FDO         Fdo,
     IN  KINTERRUPT_MODE     InterruptMode,
     IN  ULONG               Cpu,
     IN  KSERVICE_ROUTINE    Callback,
-    IN  PVOID               Argument OPTIONAL,
-    OUT PXENBUS_INTERRUPT   *Interrupt
+    IN  PVOID               Argument OPTIONAL
     );
 
 extern UCHAR