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