[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH][Linux] Fix access to xenstore hangs afterhotremove CPU



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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.