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@xxxxxxxxx>
---
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;
};
03-pcpu_hotplug.patch
Description: 03-pcpu_hotplug.patch
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|