lkml.org 
[lkml]   [2011]   [Dec]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 04/10] Xen: Add pcpu hotadd support to pvops dom0.
Date
From 5f5eb7bf950836edb4910173d3be2f26ad737093 Mon Sep 17 00:00:00 2001
From: Liu Jinsong <jinsong.liu@intel.com>
Date: Sun, 11 Dec 2011 15:42:03 +0800
Subject: [PATCH 04/10] Xen: Add pcpu hotadd support to pvops dom0.

This patch rebased from Jeremy's pvops commit
3129884bc75d7e6578be7499ac04a06d9fc5b31d

This patch implement CPU hotplug callback in xen acpi_processor. User
can later bring the pcpu online through sysfs interface.

xen_get_apic_id() is mostly duplicated with the get_cpu_id() in
driver/acpi/processor_core.c, but it should be ok since it has been
duplicated in arch directory already by upstream kernel.

One thing left is, currently the acpi_processor's id is quite
confusing (it is in fact with vcpu's dom0 cpu_id). Will update it with
xen's cpuid through the pcpu interface. But to achieve it, we need
investigate more on the pr->id, and also we need change the pcpu logic
to use spin_lock, instead of mutex for the pcpu list. That will be
next step.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
drivers/xen/acpi_processor.c | 114 +++++++++++++++++++++++++++++++++++++-
include/xen/interface/platform.h | 10 +++-
2 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/drivers/xen/acpi_processor.c b/drivers/xen/acpi_processor.c
index 327a56e..acab49b 100644
--- a/drivers/xen/acpi_processor.c
+++ b/drivers/xen/acpi_processor.c
@@ -22,12 +22,19 @@
#include <linux/cpufreq.h>
#include <acpi/processor.h>
#include <xen/acpi.h>
+#include <xen/pcpu.h>

#include <xen/interface/platform.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>

-static struct processor_cntl_xen_ops xen_ops;
+static int xen_get_apic_id(acpi_handle handle);
+static int xen_cpu_hotplug_notifier(struct acpi_processor *pr, int event);
+
+static struct processor_cntl_xen_ops xen_ops = {
+ .hotplug = xen_cpu_hotplug_notifier,
+};
+
int processor_cntl_xen_notify(struct acpi_processor *pr, int event, int type)
{
int ret = -EINVAL;
@@ -41,6 +48,18 @@ int processor_cntl_xen_notify(struct acpi_processor *pr, int event, int type)

ret = xen_ops.pm_ops[type](pr, event);
break;
+ case PROCESSOR_HOTPLUG:
+ {
+ int apic_id;
+
+ apic_id = xen_get_apic_id(pr->handle);
+ if (apic_id < 0)
+ break;
+ if (xen_ops.hotplug)
+ ret = xen_ops.hotplug(pr, type);
+ xen_pcpu_hotplug(type, apic_id);
+ break;
+ }
default:
printk(KERN_ERR "Unsupport processor events %d.\n", event);
break;
@@ -50,6 +69,49 @@ int processor_cntl_xen_notify(struct acpi_processor *pr, int event, int type)
}
EXPORT_SYMBOL(processor_cntl_xen_notify);

+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static int xen_get_apic_id(acpi_handle handle)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ struct acpi_madt_local_apic *lapic;
+ u8 physid;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
+ return -EINVAL;
+
+ if (!buffer.length || !buffer.pointer)
+ return -EINVAL;
+
+ obj = buffer.pointer;
+ if (obj->type != ACPI_TYPE_BUFFER ||
+ obj->buffer.length < sizeof(*lapic)) {
+ kfree(buffer.pointer);
+ return -EINVAL;
+ }
+
+ lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer;
+
+ if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC ||
+ !(lapic->lapic_flags & ACPI_MADT_ENABLED)) {
+ kfree(buffer.pointer);
+ return -EINVAL;
+ }
+
+ physid = lapic->id;
+ kfree(buffer.pointer);
+ buffer.length = ACPI_ALLOCATE_BUFFER;
+ buffer.pointer = NULL;
+
+ return physid;
+}
+#else
+static int xen_get_apic_id(acpi_handle handle)
+{
+ return -1;
+}
+#endif
+
static inline void xen_convert_pct_reg(struct xen_pct_register *xpct,
struct acpi_pct_register *apct)
{
@@ -246,6 +308,56 @@ static int xen_px_notifier(struct acpi_processor *pr, int action)
return ret;
}

+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static int xen_cpu_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+ 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 = xen_get_apic_id(pr->handle);
+ 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 "Xen not support CPU hotremove\n");
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+#else
+static int xen_cpu_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+ return -ENOSYS;
+}
+#endif
+
static int __init xen_acpi_processor_extcntl_init(void)
{
unsigned int pmbits;
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index 47ffe16..9fd6b07 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -317,11 +317,18 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_pcpuinfo_t);
#define XENPF_cpu_online 56
#define XENPF_cpu_offline 57
struct xenpf_cpu_ol {
- uint32_t cpuid;
+ uint32_t cpuid;
};
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;
+};
+
struct xen_platform_op {
uint32_t cmd;
uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -339,6 +346,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;
};
--
1.6.5.6[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2011-12-23 11:31    [W:0.052 / U:0.712 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site