[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH xenbus 6/8] Make vcpu_info registration conditional on number of vCPUs



From: Paul Durrant <pdurrant@xxxxxxxxxx>

It is unnecessary to explicitly register vcpu_info structures for VMs with
XEN_LEGACY_MAX_VCPUS (32) vCPUs or fewer as the array embedded in the
shared_info structure can be used instead, saving a small amount of memory and
speeding up boot slightly. NOTE: events may only be delivered to a vCPU with a
vcpu_info structure that is available to Xen.

This patch adds a registry override in the form of a registry parameter of
the XEN driver, 'RegisterVcpuInfo'. If this parameter is present and set
to zero then vcpu_info structures are not registered (regardless of vCPU
count), meaning that event channel binding may fail for some vCPUs in the
system (i.e. those with vcpu_id >= 32). If the parameter is present and set
to a non-zero value then vcpu_info structures are always registered (as is
the case without this patch). However, if the parameter is missing (which is
the default case) then vcpu_info structures will be registered only if the
vCPU count exceeds 32.

NOTE: The logic checking XEN_LEGACY_MAX_VCPUS in EvtchnIsProcessorEnabled()
      doesn't really belong there. The code in shared_info.c knows whether
      a vcpu_info is available but querying this will require a new version
      of XENBUS_SHARED_INFO. This will be addressed in a subsequent patch.

Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
 src/xen/system.c         | 54 ++++++++++++++++++++++++++++++++--------
 src/xenbus/evtchn.c      | 31 ++++++++++++++++++++---
 src/xenbus/shared_info.c | 11 ++++++--
 3 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/src/xen/system.c b/src/xen/system.c
index 5323b3e11b35..f664635119fe 100644
--- a/src/xen/system.c
+++ b/src/xen/system.c
@@ -75,6 +75,7 @@ typedef struct _SYSTEM_CONTEXT {
     PHYSICAL_ADDRESS    MaximumPhysicalAddress;
     BOOLEAN             RealTimeIsUniversal;
     SYSTEM_WATCHDOG     Watchdog;
+    BOOLEAN             RegisterVcpuInfo;
     PMDL                Mdl;
 } SYSTEM_CONTEXT, *PSYSTEM_CONTEXT;
 
@@ -664,11 +665,16 @@ SystemProcessorVcpuInfo(
     if (Cpu >= Context->ProcessorCount)
         goto fail1;
 
+    status = STATUS_NOT_SUPPORTED;
+    if (Processor->Registered == NULL)
+        goto fail2;
+
     ASSERT(*Processor->Registered);
     *Vcpu = Processor->Vcpu;
 
     return STATUS_SUCCESS;
 
+fail2:
 fail1:
     return status;
 }
@@ -689,6 +695,8 @@ SystemProcessorRegisterVcpuInfo(
     PUCHAR              MdlMappedSystemVa;
     NTSTATUS            status;
 
+    ASSERT(Context->RegisterVcpuInfo);
+
     status = STATUS_UNSUCCESSFUL;
     if (Cpu >= Context->ProcessorCount)
         goto fail1;
@@ -756,6 +764,8 @@ SystemProcessorDeregisterVcpuInfo(
     PSYSTEM_CONTEXT     Context = &SystemContext;
     PSYSTEM_PROCESSOR   Processor = &Context->Processor[Cpu];
 
+    ASSERT(Context->RegisterVcpuInfo);
+
     Processor->Vcpu = NULL;
     Processor->Registered = NULL;
 }
@@ -795,9 +805,11 @@ SystemProcessorDpc(
 
     SystemProcessorInitialize(Cpu);
 
-    status = SystemProcessorRegisterVcpuInfo(Cpu, FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
+    if (Context->RegisterVcpuInfo) {
+        status = SystemProcessorRegisterVcpuInfo(Cpu, FALSE);
+        if (!NT_SUCCESS(status))
+            goto fail1;
+    }
 
     Info("<==== (%u:%u)\n", ProcNumber.Group, ProcNumber.Number);
 
@@ -843,7 +855,6 @@ SystemProcessorChangeCallback(
     switch (Change->State) {
     case KeProcessorAddStartNotify:
         break;
-
     case KeProcessorAddCompleteNotify: {
         PSYSTEM_PROCESSOR   Processor;
 
@@ -893,6 +904,8 @@ SystemAllocateVcpuInfo(
     ULONG           Size;
     NTSTATUS        status;
 
+    ASSERT(Context->RegisterVcpuInfo);
+
     Size = sizeof (vcpu_info_t) * HVM_MAX_VCPUS;
     Size += sizeof (BOOLEAN) * HVM_MAX_VCPUS;
     Size = P2ROUNDUP(Size, PAGE_SIZE);
@@ -918,6 +931,8 @@ SystemFreeVcpuInfo(
 {
     PSYSTEM_CONTEXT Context = &SystemContext;
 
+    ASSERT(Context->RegisterVcpuInfo);
+
     DriverPutNamedPages(Context->Mdl);
     Context->Mdl = NULL;
 }
@@ -931,9 +946,11 @@ SystemRegisterProcessorChangeCallback(
     PVOID           Handle;
     NTSTATUS        status;
 
-    status = SystemAllocateVcpuInfo();
-    if (!NT_SUCCESS(status))
-        goto fail1;
+    if (Context->RegisterVcpuInfo) {
+        status = SystemAllocateVcpuInfo();
+        if (!NT_SUCCESS(status))
+            goto fail1;
+    }
 
     Handle = KeRegisterProcessorChangeCallback(SystemProcessorChangeCallback,
                                                NULL,
@@ -950,7 +967,8 @@ SystemRegisterProcessorChangeCallback(
 fail2:
     Error("fail2\n");
 
-    SystemFreeVcpuInfo();
+    if (Context->RegisterVcpuInfo)
+        SystemFreeVcpuInfo();
 
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -972,7 +990,9 @@ SystemDeregisterProcessorChangeCallback(
     for (Cpu = 0; Cpu < Context->ProcessorCount; Cpu++) {
         PSYSTEM_PROCESSOR   Processor = &Context->Processor[Cpu];
 
-        SystemProcessorDeregisterVcpuInfo(Cpu);
+        if (Context->RegisterVcpuInfo)
+            SystemProcessorDeregisterVcpuInfo(Cpu);
+
         SystemProcessorTeardown(Cpu);
 
         RtlZeroMemory(&Processor->Dpc, sizeof (KDPC));
@@ -982,7 +1002,8 @@ SystemDeregisterProcessorChangeCallback(
         ASSERT(IsZeroMemory(Processor, sizeof (SYSTEM_PROCESSOR)));
     }
 
-    SystemFreeVcpuInfo();
+    if (Context->RegisterVcpuInfo)
+        SystemFreeVcpuInfo();
 }
 
 static NTSTATUS
@@ -1221,6 +1242,8 @@ SystemInitialize(
 {
     PSYSTEM_CONTEXT Context = &SystemContext;
     LONG            References;
+    HANDLE          ParametersKey;
+    ULONG           RegisterVcpuInfo;
     NTSTATUS        status;
 
     References = InterlockedIncrement(&Context->References);
@@ -1236,6 +1259,17 @@ SystemInitialize(
     if (Context->Processor == NULL)
         goto fail2;
 
+    ParametersKey = DriverGetParametersKey();
+
+    status = RegistryQueryDwordValue(ParametersKey,
+                                     "RegisterVcpuInfo",
+                                     &RegisterVcpuInfo);
+    if (NT_SUCCESS(status))
+        Context->RegisterVcpuInfo = (RegisterVcpuInfo != 0) ? TRUE : FALSE;
+    else
+        Context->RegisterVcpuInfo = (Context->ProcessorCount > 
XEN_LEGACY_MAX_VCPUS) ?
+                                    TRUE : FALSE;
+
     status = SystemGetStartOptions();
     if (!NT_SUCCESS(status))
         goto fail3;
diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c
index d0702686aeea..97664524e737 100644
--- a/src/xenbus/evtchn.c
+++ b/src/xenbus/evtchn.c
@@ -1506,6 +1506,33 @@ EvtchnDebugCallback(
     }
 }
 
+static BOOLEAN
+EvtchnIsProcessorEnabled(
+    IN  PXENBUS_EVTCHN_CONTEXT      Context,
+    IN  ULONG                       Cpu
+    )
+{
+    vcpu_info_t                     *Vcpu;
+    NTSTATUS                        status;
+
+    status = SystemProcessorVcpuInfo(Cpu, &Vcpu);
+    if (!NT_SUCCESS(status)) {
+        unsigned int    vcpu_id;
+
+        ASSERT(status == STATUS_NOT_SUPPORTED);
+
+        status = SystemProcessorVcpuId(Cpu, &vcpu_id);
+        ASSERT(NT_SUCCESS(status));
+
+        if (vcpu_id >= XEN_LEGACY_MAX_VCPUS)
+            return FALSE;
+    }
+
+    return XENBUS_EVTCHN_ABI(IsProcessorEnabled,
+                             &Context->EvtchnAbi,
+                             Cpu);
+}
+
 static NTSTATUS
 EvtchnAcquire(
     IN  PINTERFACE          Interface
@@ -1578,9 +1605,7 @@ EvtchnAcquire(
     for (Cpu = 0; Cpu < Context->ProcessorCount; Cpu++) {
         PXENBUS_EVTCHN_PROCESSOR    Processor;
 
-        if (!XENBUS_EVTCHN_ABI(IsProcessorEnabled,
-                               &Context->EvtchnAbi,
-                               Cpu))
+        if (!EvtchnIsProcessorEnabled(Context, Cpu))
             continue;
 
         status = KeGetProcessorNumberFromIndex(Cpu, &ProcNumber);
diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c
index 20f07a82d801..984ee6ff0417 100644
--- a/src/xenbus/shared_info.c
+++ b/src/xenbus/shared_info.c
@@ -629,8 +629,15 @@ SharedInfoAcquire(
             goto fail7;
 
         status = SystemProcessorVcpuInfo(Index, &Processor->Vcpu);
-        if (!NT_SUCCESS(status) && status != STATUS_NOT_SUPPORTED)
-            goto fail8;
+        if (!NT_SUCCESS(status)) {
+            if (status != STATUS_NOT_SUPPORTED)
+                goto fail8;
+
+            if (Processor->vcpu_id >= ARRAYSIZE(Shared->vcpu_info))
+                continue;
+
+            Processor->Vcpu = &Shared->vcpu_info[Processor->vcpu_id];
+        }
     }
 
     Trace("<====\n");
-- 
2.17.1




 


Rackspace

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