ia64/xen-unstable

changeset 7351:def91f2dbc89

Fix vcpu-hotplug xenbus watch handler and setup.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Oct 12 11:47:16 2005 +0100 (2005-10-12)
parents 43b40ae7904c
children b719806d1265 68e754d7e1cb
files linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Wed Oct 12 11:13:00 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Wed Oct 12 11:47:16 2005 +0100
     1.3 @@ -64,6 +64,7 @@
     1.4  
     1.5  #include <asm-xen/evtchn.h>
     1.6  #include <asm-xen/xen-public/vcpu.h>
     1.7 +#include <asm-xen/xenbus.h>
     1.8  
     1.9  /* Set if we find a B stepping CPU */
    1.10  static int __initdata smp_b_stepping;
    1.11 @@ -1289,117 +1290,51 @@ void __devinit smp_prepare_boot_cpu(void
    1.12  }
    1.13  
    1.14  #ifdef CONFIG_HOTPLUG_CPU
    1.15 -#include <asm-xen/xenbus.h>
    1.16 -/* hotplug down/up funtion pointer and target vcpu */
    1.17 -struct vcpu_hotplug_handler_t {
    1.18 -	void (*fn) (int vcpu);
    1.19 -	u32 vcpu;
    1.20 -};
    1.21 -static struct vcpu_hotplug_handler_t vcpu_hotplug_handler;
    1.22  
    1.23 -static int vcpu_hotplug_cpu_process(void *unused)
    1.24 +static void handle_vcpu_hotplug_event(
    1.25 +	struct xenbus_watch *watch, const char **vec, unsigned int len)
    1.26  {
    1.27 -	struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler;
    1.28 +	int err, cpu;
    1.29 +	char dir[32], state[32];
    1.30 +	char *cpustr;
    1.31 +	const char *node = vec[XS_WATCH_PATH];
    1.32  
    1.33 -	if (handler->fn) {
    1.34 -		(*(handler->fn)) (handler->vcpu);
    1.35 -		handler->fn = NULL;
    1.36 -	}
    1.37 -	return 0;
    1.38 -}
    1.39 +	if ((cpustr = strstr(node, "cpu/")) == NULL)
    1.40 +		return;
    1.41 +
    1.42 +	sscanf(cpustr, "cpu/%d", &cpu);
    1.43  
    1.44 -static void __vcpu_hotplug_handler(void *unused)
    1.45 -{
    1.46 -	int err;
    1.47 +	sprintf(dir, "cpu/%d", cpu);
    1.48 +	err = xenbus_scanf(NULL, dir, "availability", "%s", state);
    1.49 +	if (err != 1) {
    1.50 +		printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
    1.51 +		return;
    1.52 +	}
    1.53  
    1.54 -	err = kernel_thread(vcpu_hotplug_cpu_process,
    1.55 -			    NULL, CLONE_FS | CLONE_FILES);
    1.56 -	if (err < 0)
    1.57 -		printk(KERN_ALERT "Error creating hotplug_cpu process!\n");
    1.58 +	if (strcmp(state, "online") == 0)
    1.59 +		(void)cpu_up(cpu);
    1.60 +	else if (strcmp(state, "offline") == 0)
    1.61 +		(void)cpu_down(cpu);
    1.62 +	else
    1.63 +		printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n",
    1.64 +		       state, node);
    1.65  }
    1.66  
    1.67 -static void handle_vcpu_hotplug_event(struct xenbus_watch *, const char *);
    1.68 -static struct notifier_block xsn_cpu;
    1.69 -
    1.70 -/* xenbus watch struct */
    1.71 -static struct xenbus_watch cpu_watch = {
    1.72 -	.node = "cpu",
    1.73 -	.callback = handle_vcpu_hotplug_event
    1.74 -};
    1.75 -
    1.76  static int setup_cpu_watcher(struct notifier_block *notifier,
    1.77  			      unsigned long event, void *data)
    1.78  {
    1.79 -	int err;
    1.80 -
    1.81 -	err = register_xenbus_watch(&cpu_watch);
    1.82 -	if (err)
    1.83 -		printk("Failed to register watch on /cpu\n");
    1.84 -
    1.85 +	static struct xenbus_watch cpu_watch = {
    1.86 +		.node = "cpu",
    1.87 +		.callback = handle_vcpu_hotplug_event };
    1.88 +	(void)register_xenbus_watch(&cpu_watch);
    1.89  	return NOTIFY_DONE;
    1.90  }
    1.91  
    1.92 -static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, const char *node)
    1.93 -{
    1.94 -	static DECLARE_WORK(vcpu_hotplug_work, __vcpu_hotplug_handler, NULL);
    1.95 -	struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler;
    1.96 -	ssize_t ret;
    1.97 -	int err, cpu;
    1.98 -	char state[8];
    1.99 -	char dir[32];
   1.100 -	char *cpustr;
   1.101 -
   1.102 -	/* get a pointer to start of cpu string */
   1.103 -	if ((cpustr = strstr(node, "cpu/")) != NULL) {
   1.104 -
   1.105 -		/* find which cpu state changed, note vcpu for handler */
   1.106 -		sscanf(cpustr, "cpu/%d", &cpu);
   1.107 -		handler->vcpu = cpu;
   1.108 -
   1.109 -		/* calc the dir for xenbus read */
   1.110 -		sprintf(dir, "cpu/%d", cpu);
   1.111 -
   1.112 -		/* make sure watch that was triggered is changes to the correct key */
   1.113 -		if ((strcmp(node + strlen(dir), "/availability")) != 0)
   1.114 -			return;
   1.115 -
   1.116 -		/* get the state value */
   1.117 -		err = xenbus_scanf(NULL, dir, "availability", "%s", state);
   1.118 -
   1.119 -		if (err != 1) {
   1.120 -			printk(KERN_ERR
   1.121 -			       "XENBUS: Unable to read cpu state\n");
   1.122 -			return;
   1.123 -		}
   1.124 -
   1.125 -		/* if we detect a state change, take action */
   1.126 -		if (strcmp(state, "online") == 0) {
   1.127 -			/* offline -> online */
   1.128 -			if (!cpu_isset(cpu, cpu_online_map)) {
   1.129 -				handler->fn = (void *)&cpu_up;
   1.130 -				ret = schedule_work(&vcpu_hotplug_work);
   1.131 -			} 
   1.132 -		} else if (strcmp(state, "offline") == 0) {
   1.133 -			/* online -> offline */
   1.134 -			if (cpu_isset(cpu, cpu_online_map)) {
   1.135 -				handler->fn = (void *)&cpu_down;
   1.136 -				ret = schedule_work(&vcpu_hotplug_work);
   1.137 -			} 
   1.138 -		} else {
   1.139 -			printk(KERN_ERR
   1.140 -			       "XENBUS: unknown state(%s) on node(%s)\n", state,
   1.141 -			       node);
   1.142 -		}
   1.143 -	}
   1.144 -	return;
   1.145 -}
   1.146 -
   1.147  static int __init setup_vcpu_hotplug_event(void)
   1.148  {
   1.149 -	xsn_cpu.notifier_call = setup_cpu_watcher;
   1.150 -
   1.151 +	static struct notifier_block xsn_cpu = {
   1.152 +		.notifier_call = setup_cpu_watcher };
   1.153  	register_xenstore_notifier(&xsn_cpu);
   1.154 -
   1.155  	return 0;
   1.156  }
   1.157  
   1.158 @@ -1623,3 +1558,13 @@ void vcpu_prepare(int vcpu)
   1.159  	(void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt);
   1.160  	(void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
   1.161  }
   1.162 +
   1.163 +/*
   1.164 + * Local variables:
   1.165 + *  c-file-style: "linux"
   1.166 + *  indent-tabs-mode: t
   1.167 + *  c-indent-level: 8
   1.168 + *  c-basic-offset: 8
   1.169 + *  tab-width: 8
   1.170 + * End:
   1.171 + */