diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-06-21 10:53:51 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-06-21 10:53:51 +0000 |
commit | be51472d620db0a00f53cca9810ad39d52277e08 (patch) | |
tree | 92b99bb420962978249e8a3b8167a1ec33475d28 /linux-2.6.11-xen-sparse | |
parent | 116e79a98faa4efb87f73d9e32d8cfc8f5a979ce (diff) | |
download | xen-be51472d620db0a00f53cca9810ad39d52277e08.tar.gz xen-be51472d620db0a00f53cca9810ad39d52277e08.tar.bz2 xen-be51472d620db0a00f53cca9810ad39d52277e08.zip |
bitkeeper revision 1.1726 (42b7f1bfzMUFLRiUR9wWkzc2mh-Ing)
Add new control messages for vcpu hotplug events. Via the
xm vcpu-hotplug sub-program, vcpus in domains can be enabled/disabled
when CONFIG_HOTPLUG_CPU is enabled in the target domain's kernel.
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Diffstat (limited to 'linux-2.6.11-xen-sparse')
-rw-r--r-- | linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c index 9395238532..14342b66de 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -1303,6 +1303,14 @@ void __devinit smp_prepare_boot_cpu(void) } #ifdef CONFIG_HOTPLUG_CPU +#include <asm-xen/ctrl_if.h> + +/* hotplug down/up funtion pointer and target vcpu */ +struct vcpu_hotplug_handler_t { + void (*fn)(); + u32 vcpu; +}; +static struct vcpu_hotplug_handler_t vcpu_hotplug_handler; /* must be called with the cpucontrol mutex held */ static int __devinit cpu_enable(unsigned int cpu) @@ -1374,6 +1382,78 @@ void __cpu_die(unsigned int cpu) } printk(KERN_ERR "CPU %u didn't die...\n", cpu); } + +static int vcpu_hotplug_cpu_process(void *unused) +{ + struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler; + + if (handler->fn) { + (*(handler->fn))(handler->vcpu); + handler->fn = NULL; + } + return 0; +} + +static void __vcpu_hotplug_handler(void *unused) +{ + int err; + + err = kernel_thread(vcpu_hotplug_cpu_process, + NULL, CLONE_FS | CLONE_FILES); + if (err < 0) + printk(KERN_ALERT "Error creating hotplug_cpu process!\n"); + +} + +static void vcpu_hotplug_event_handler(ctrl_msg_t *msg, unsigned long id) +{ + static DECLARE_WORK(vcpu_hotplug_work, __vcpu_hotplug_handler, NULL); + vcpu_hotplug_t *req = (vcpu_hotplug_t *)&msg->msg[0]; + struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler; + ssize_t ret; + + if (msg->length != sizeof(vcpu_hotplug_t)) + goto parse_error; + + /* grab target vcpu from msg */ + handler->vcpu = req->vcpu; + + /* determine which function to call based on msg subtype */ + switch (msg->subtype) { + case CMSG_VCPU_HOTPLUG_OFF: + handler->fn = (void *)&cpu_down; + ret = schedule_work(&vcpu_hotplug_work); + req->status = (u32) ret; + break; + case CMSG_VCPU_HOTPLUG_ON: + handler->fn = (void *)&cpu_up; + ret = schedule_work(&vcpu_hotplug_work); + req->status = (u32) ret; + break; + default: + goto parse_error; + } + + ctrl_if_send_response(msg); + return; + parse_error: + msg->length = 0; + ctrl_if_send_response(msg); +} + +static int __init setup_vcpu_hotplug_event(void) +{ + struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler; + + handler->fn = NULL; + ctrl_if_register_receiver(CMSG_VCPU_HOTPLUG, + vcpu_hotplug_event_handler, 0); + + return 0; +} + +__initcall(setup_vcpu_hotplug_event); + #else /* ... !CONFIG_HOTPLUG_CPU */ int __cpu_disable(void) { |