Jiang, Yunhong
2009-Nov-12 15:45 UTC
[Xen-devel] [PATCH][DOM0] Add CPU hotplug support to PV_ops dom0
This patch add cpu hotplug support to dom0. It''s function depends on previous patch of "Expose physical CPU information in dom0". It implement xen''s acpi notifier, so that when a CPU hotplug event happen, it will notify xen hypervisor. Currently only support cpu hot-add. Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com> --- drivers/acpi/processor_core.c | 17 ++++++------- drivers/xen/acpi_processor.c | 48 +++++++++++++++++++++++++++++++++++++- include/xen/interface/platform.h | 28 +++++++++++++++------- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a448ba6..27c1849 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -663,7 +663,7 @@ static int acpi_processor_get_info(struct acpi_device *device) * less than the max # of CPUs. They should be ignored _iff * they are physically not present. */ - if (pr->id == -1) { + if (!xen_pv_domain() && (pr->id == -1)) { if (ACPI_FAILURE (acpi_processor_hotadd_init(pr->handle, &pr->id))) { return -ENODEV; @@ -751,6 +751,10 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) per_cpu(processors, pr->id) = pr; + if (processor_cntl_xen()) + processor_cntl_xen_notify(pr, + PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD); + result = acpi_processor_add_fs(device); if (result) goto end; @@ -990,10 +994,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) if (!pr) return -ENODEV; - if (processor_cntl_xen()) - processor_cntl_xen_notify(pr, - PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD); - if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); } @@ -1039,13 +1039,12 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + if (processor_cntl_xen()) + processor_cntl_xen_notify(pr, PROCESSOR_HOTPLUG, + HOTPLUG_TYPE_REMOVE); break; } - if (processor_cntl_xen()) - processor_cntl_xen_notify(pr, PROCESSOR_HOTPLUG, - HOTPLUG_TYPE_REMOVE); - result = acpi_processor_start(device); if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); diff --git a/drivers/xen/acpi_processor.c b/drivers/xen/acpi_processor.c index 6a4e8e4..9834e45 100644 --- a/drivers/xen/acpi_processor.c +++ b/drivers/xen/acpi_processor.c @@ -32,6 +32,7 @@ #include <linux/cpufreq.h> #include <acpi/processor.h> #include <xen/acpi.h> +#include <xen/pcpu.h> #include <asm/xen/hypercall.h> #include <asm/xen/hypervisor.h> @@ -71,6 +72,8 @@ int processor_cntl_xen_power_cache(int cpu, int cx, int processor_cntl_xen(void) { + if (!xen_initial_domain()) + return 0; return 1; } @@ -122,6 +125,7 @@ static int processor_notify_smm(void) int processor_cntl_xen_notify(struct acpi_processor *pr, int event, int type) { int ret = -EINVAL; + int apic_id; switch (event) { case PROCESSOR_PM_INIT: @@ -135,6 +139,8 @@ int processor_cntl_xen_notify(struct acpi_processor *pr, int event, int type) case PROCESSOR_HOTPLUG: if (xen_ops.hotplug) ret = xen_ops.hotplug(pr, type); + apic_id = get_apic_id(pr->handle, 1, pr->acpi_id); + xen_pcpu_hotplug(type, apic_id); break; default: printk(KERN_ERR "Unsupport processor events %d.\n", event); @@ -423,9 +429,49 @@ static int xen_tx_notifier(struct acpi_processor *pr, int action) { return -EINVAL; } + static int xen_hotplug_notifier(struct acpi_processor *pr, int event) { - return -EINVAL; + int ret = -EINVAL; + uint32_t apic_id; + unsigned long long pxm; + acpi_status status = 0; + + xen_platform_op_t op = { + .interface_version = XENPF_INTERFACE_VERSION, + }; + + apic_id = get_apic_id(pr->handle, 1, pr->acpi_id); + if (apic_id < 0) { + printk(KERN_WARNING "Can''t get apic_id for acpi_id %x\n", + pr->acpi_id); + return -1; + } + + status = acpi_evaluate_integer(pr->handle, "_PXM", + NULL, &pxm); + if (ACPI_FAILURE(status)) { + printk(KERN_WARNING "can''t get pxm for acpi_id %x\n", + pr->acpi_id); + return -1; + } + + switch (event) { + case HOTPLUG_TYPE_ADD: + op.cmd = XENPF_cpu_hotadd; + op.u.cpu_add.apic_id = apic_id; + op.u.cpu_add.acpi_id = pr->acpi_id; + op.u.cpu_add.pxm = pxm; + + ret = HYPERVISOR_dom0_op(&op); + break; + case HOTPLUG_TYPE_REMOVE: + printk(KERN_WARNING "No support for CPU hot-remove in xen\n"); + ret = -ENOSYS; + break; + } + + return ret; } static int __init xen_acpi_processor_extcntl_init(void) diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h index 14df81d..0bef928 100644 --- a/include/xen/interface/platform.h +++ b/include/xen/interface/platform.h @@ -314,17 +314,17 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_set_processor_pminfo); #define XENPF_get_cpuinfo 55 struct xenpf_pcpuinfo { - /* IN */ - uint32_t xen_cpuid; - /* OUT */ - /* The maxium cpu_id that is present */ - uint32_t max_present; + /* IN */ + uint32_t xen_cpuid; + /* OUT */ + /* The maxium cpu_id that is present */ + uint32_t max_present; #define XEN_PCPU_FLAGS_ONLINE 1 - /* Correponding xen_cpuid is not present*/ + /* Correponding xen_cpuid is not present*/ #define XEN_PCPU_FLAGS_INVALID 2 - uint32_t flags; - uint32_t apic_id; - uint32_t acpi_id; + uint32_t flags; + uint32_t apic_id; + uint32_t acpi_id; }; typedef struct xenpf_pcpuinfo xenpf_pcpuinfo_t; DEFINE_GUEST_HANDLE_STRUCT(xenpf_pcpuinfo_t); @@ -337,6 +337,15 @@ struct xenpf_cpu_ol { typedef struct xenpf_cpu_ol xenpf_cpu_ol_t; DEFINE_GUEST_HANDLE_STRUCT(xenpf_cpu_ol_t); +#define XENPF_cpu_hotadd 58 +struct xenpf_cpu_hotadd { + uint32_t apic_id; + uint32_t acpi_id; + uint32_t pxm; +}; +typedef struct xenpf_cpu_hotadd xenpf_cpu_hotadd_t; +DEFINE_GUEST_HANDLE_STRUCT(xenpf_cpu_hotadd_t); + struct xen_platform_op { uint32_t cmd; uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ @@ -354,6 +363,7 @@ struct xen_platform_op { struct xenpf_set_processor_pminfo set_pminfo; struct xenpf_pcpuinfo pcpu_info; struct xenpf_cpu_ol cpu_ol; + struct xenpf_cpu_hotadd cpu_add; uint8_t pad[128]; } u; }; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel