I see. Thanks for pointing out.
Revised patch attached.
Thanks,
Kouya
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
Jan Beulich writes:
> Using __cpuinitdata (or __cpuinit) in #ifdef CONFIG_HOTPLUG_CPU sections
> is pointless. Either remove the #ifdef-s (and mark evtchn_cpu_notify()
> __cpuinit) or remove the __cpuinitdata. I think the former is the preferred
> upstream approach.
>
> Jan
>
> >>> Kouya Shimura <kouya@xxxxxxxxxxxxxx> 27.11.07 05:24 >>>
> Hi,
>
> CPU hotplug doesn't support user-space event channels.
>
> $ echo 0 > /sys/devices/system/cpu/cpu1/online
> $ xenstore-ls
> ... hangs up ...
>
> Attached patch fixes it.
>
> Thanks,
> Kouya
>
> Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel
diff -r fd879c0688bf drivers/xen/evtchn/evtchn.c
--- a/drivers/xen/evtchn/evtchn.c Fri Nov 23 16:26:56 2007 +0000
+++ b/drivers/xen/evtchn/evtchn.c Tue Nov 27 19:15:04 2007 +0900
@@ -48,6 +48,7 @@
#include <linux/init.h>
#include <linux/gfp.h>
#include <linux/mutex.h>
+#include <linux/cpu.h>
#include <xen/evtchn.h>
#include <xen/public/evtchn.h>
@@ -231,6 +232,15 @@ static ssize_t evtchn_write(struct file
return rc;
}
+static unsigned int next_bind_cpu(cpumask_t map)
+{
+ static unsigned int bind_cpu;
+ bind_cpu = next_cpu(bind_cpu, map);
+ if (bind_cpu >= NR_CPUS)
+ bind_cpu = first_cpu(map);
+ return bind_cpu;
+}
+
static void evtchn_bind_to_user(struct per_user_data *u, int port)
{
spin_lock_irq(&port_user_lock);
@@ -238,13 +248,8 @@ static void evtchn_bind_to_user(struct p
BUG_ON(port_user[port] != NULL);
port_user[port] = u;
- if (u->bind_cpu == -1) {
- static unsigned int bind_cpu;
- bind_cpu = next_cpu(bind_cpu, cpu_online_map);
- if (bind_cpu >= NR_CPUS)
- bind_cpu = first_cpu(cpu_online_map);
- u->bind_cpu = bind_cpu;
- }
+ if (u->bind_cpu == -1)
+ u->bind_cpu = next_bind_cpu(cpu_online_map);
rebind_evtchn_to_cpu(port, u->bind_cpu);
@@ -483,6 +488,38 @@ static struct miscdevice evtchn_miscdev
.fops = &evtchn_fops,
};
+static int __cpuinit evtchn_cpu_notify(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ int hotcpu = (unsigned long)hcpu;
+ cpumask_t map = cpu_online_map;
+ int port, newcpu;
+ struct per_user_data *u;
+
+ switch (action) {
+ case CPU_DOWN_PREPARE:
+ cpu_clear(hotcpu, map);
+ spin_lock_irq(&port_user_lock);
+ for (port = 0; port < NR_EVENT_CHANNELS; port++) {
+ if ((u = port_user[port]) != NULL &&
+ u->bind_cpu == hotcpu &&
+ (newcpu = next_bind_cpu(map)) < NR_CPUS) {
+ rebind_evtchn_to_cpu(port, newcpu);
+ u->bind_cpu = newcpu;
+ }
+ }
+ spin_unlock_irq(&port_user_lock);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata evtchn_cpu_nfb = {
+ .notifier_call = evtchn_cpu_notify
+};
+
static int __init evtchn_init(void)
{
int err;
@@ -500,6 +537,8 @@ static int __init evtchn_init(void)
return err;
}
+ register_cpu_notifier(&evtchn_cpu_nfb);
+
printk("Event-channel device installed.\n");
return 0;
@@ -508,6 +547,7 @@ static void evtchn_cleanup(void)
static void evtchn_cleanup(void)
{
misc_deregister(&evtchn_miscdev);
+ unregister_cpu_notifier(&evtchn_cpu_nfb);
}
module_init(evtchn_init);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|