Mailing List Archive

Fix vcpu-hotplug xenbus watch handler and setup.
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID def91f2dbc890da85a6e159d71a30ff6157a7a9f
# Parent 43b40ae7904c6d0121e9a2e547b8d814945ca2ac
Fix vcpu-hotplug xenbus watch handler and setup.
Signed-off-by: Keir Fraser <keir@xensource.com>

diff -r 43b40ae7904c -r def91f2dbc89 linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Wed Oct 12 10:13:00 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Wed Oct 12 10:47:16 2005
@@ -64,6 +64,7 @@

#include <asm-xen/evtchn.h>
#include <asm-xen/xen-public/vcpu.h>
+#include <asm-xen/xenbus.h>

/* Set if we find a B stepping CPU */
static int __initdata smp_b_stepping;
@@ -1289,117 +1290,51 @@
}

#ifdef CONFIG_HOTPLUG_CPU
-#include <asm-xen/xenbus.h>
-/* hotplug down/up funtion pointer and target vcpu */
-struct vcpu_hotplug_handler_t {
- void (*fn) (int vcpu);
- u32 vcpu;
-};
-static struct vcpu_hotplug_handler_t vcpu_hotplug_handler;
-
-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 handle_vcpu_hotplug_event(struct xenbus_watch *, const char *);
-static struct notifier_block xsn_cpu;
-
-/* xenbus watch struct */
-static struct xenbus_watch cpu_watch = {
- .node = "cpu",
- .callback = handle_vcpu_hotplug_event
-};
+
+static void handle_vcpu_hotplug_event(
+ struct xenbus_watch *watch, const char **vec, unsigned int len)
+{
+ int err, cpu;
+ char dir[32], state[32];
+ char *cpustr;
+ const char *node = vec[XS_WATCH_PATH];
+
+ if ((cpustr = strstr(node, "cpu/")) == NULL)
+ return;
+
+ sscanf(cpustr, "cpu/%d", &cpu);
+
+ sprintf(dir, "cpu/%d", cpu);
+ err = xenbus_scanf(NULL, dir, "availability", "%s", state);
+ if (err != 1) {
+ printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
+ return;
+ }
+
+ if (strcmp(state, "online") == 0)
+ (void)cpu_up(cpu);
+ else if (strcmp(state, "offline") == 0)
+ (void)cpu_down(cpu);
+ else
+ printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n",
+ state, node);
+}

static int setup_cpu_watcher(struct notifier_block *notifier,
unsigned long event, void *data)
{
- int err;
-
- err = register_xenbus_watch(&cpu_watch);
- if (err)
- printk("Failed to register watch on /cpu\n");
-
+ static struct xenbus_watch cpu_watch = {
+ .node = "cpu",
+ .callback = handle_vcpu_hotplug_event };
+ (void)register_xenbus_watch(&cpu_watch);
return NOTIFY_DONE;
}

-static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, const char *node)
-{
- static DECLARE_WORK(vcpu_hotplug_work, __vcpu_hotplug_handler, NULL);
- struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler;
- ssize_t ret;
- int err, cpu;
- char state[8];
- char dir[32];
- char *cpustr;
-
- /* get a pointer to start of cpu string */
- if ((cpustr = strstr(node, "cpu/")) != NULL) {
-
- /* find which cpu state changed, note vcpu for handler */
- sscanf(cpustr, "cpu/%d", &cpu);
- handler->vcpu = cpu;
-
- /* calc the dir for xenbus read */
- sprintf(dir, "cpu/%d", cpu);
-
- /* make sure watch that was triggered is changes to the correct key */
- if ((strcmp(node + strlen(dir), "/availability")) != 0)
- return;
-
- /* get the state value */
- err = xenbus_scanf(NULL, dir, "availability", "%s", state);
-
- if (err != 1) {
- printk(KERN_ERR
- "XENBUS: Unable to read cpu state\n");
- return;
- }
-
- /* if we detect a state change, take action */
- if (strcmp(state, "online") == 0) {
- /* offline -> online */
- if (!cpu_isset(cpu, cpu_online_map)) {
- handler->fn = (void *)&cpu_up;
- ret = schedule_work(&vcpu_hotplug_work);
- }
- } else if (strcmp(state, "offline") == 0) {
- /* online -> offline */
- if (cpu_isset(cpu, cpu_online_map)) {
- handler->fn = (void *)&cpu_down;
- ret = schedule_work(&vcpu_hotplug_work);
- }
- } else {
- printk(KERN_ERR
- "XENBUS: unknown state(%s) on node(%s)\n", state,
- node);
- }
- }
- return;
-}
-
static int __init setup_vcpu_hotplug_event(void)
{
- xsn_cpu.notifier_call = setup_cpu_watcher;
-
+ static struct notifier_block xsn_cpu = {
+ .notifier_call = setup_cpu_watcher };
register_xenstore_notifier(&xsn_cpu);
-
return 0;
}

@@ -1623,3 +1558,13 @@
(void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt);
(void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
}
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog