|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |