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

[Xen-changelog] [linux-2.6.18-xen] smpboot: adjust ordering of operations



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1332754587 -7200
# Node ID b7fea0d6bf234c86e65ddf7781fdf63bb046cba6
# Parent  80ed6519816209ea16ab606a58f868eb8b90e909
smpboot: adjust ordering of operations

The primary goal of the change is to add the locking around the setting
of the cpu_online_map bit that got introduced in or before 2.6.16.

In doing so I noticed, however, that the point in time when this is
done wasn't in sync with how native does it (and in actual conflict
with additions to that code path in subsequent Linux versions). So the
setting of this bit now gets done on the CPU being brought up, and the
CPU initiating the bringup, just like on native, waits for up to 5
seconds for the remote to respond.

Finally, rather than BUG()ing on eventual errors, do proper cleanup and
return the error to the caller. Plus call xen_smp_intr_init() earlier
so that no cleanup will need to be performed in case of it failing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r 80ed65198162 -r b7fea0d6bf23 drivers/xen/core/smpboot.c
--- a/drivers/xen/core/smpboot.c        Thu Mar 15 13:40:20 2012 +0100
+++ b/drivers/xen/core/smpboot.c        Mon Mar 26 11:36:27 2012 +0200
@@ -146,7 +146,6 @@
        return rc;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 static void xen_smp_intr_exit(unsigned int cpu)
 {
        if (cpu != 0)
@@ -155,7 +154,6 @@
        unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
        unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
 }
-#endif
 
 void __cpuinit cpu_bringup(void)
 {
@@ -163,7 +161,9 @@
        identify_cpu(cpu_data + smp_processor_id());
        touch_softlockup_watchdog();
        preempt_disable();
-       local_irq_enable();
+       lock_ipi_call_lock();
+       cpu_set(smp_processor_id(), cpu_online_map);
+       unlock_ipi_call_lock();
 }
 
 static void __cpuinit cpu_bringup_and_idle(void)
@@ -414,6 +414,10 @@
        if (rc)
                return rc;
 
+       rc = xen_smp_intr_init(cpu);
+       if (rc)
+               return rc;
+
        cpu_initialize_context(cpu);
 
        if (num_online_cpus() == 1)
@@ -423,18 +427,27 @@
        set_cpu_sibling_map(cpu);
        wmb();
 
-       rc = xen_smp_intr_init(cpu);
-       if (rc) {
-               remove_siblinginfo(cpu);
-               return rc;
+       rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
+       if (!rc) {
+               /* Wait 5s total for a response. */
+               unsigned long timeout = jiffies + 5 * HZ;
+
+               while (!cpu_online(cpu) && time_before_eq(jiffies, timeout))
+                       HYPERVISOR_yield();
+               if (!cpu_online(cpu)) {
+                       VOID(HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL));
+                       rc = -ETIMEDOUT;
+               }
        }
 
-       cpu_set(cpu, cpu_online_map);
+       if (rc) {
+               xen_smp_intr_exit(cpu);
+               remove_siblinginfo(cpu);
+               if (num_online_cpus() == 1)
+                       alternatives_smp_switch(0);
+       }
 
-       rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
-       BUG_ON(rc);
-
-       return 0;
+       return rc;
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)

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


 


Rackspace

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