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

[Xen-devel] [PATCH] linux-2.6.18/smpboot: adjust ordering of operations


  • To: "xen-devel" <xen-devel@xxxxxxxxxxxxx>
  • From: "Jan Beulich" <JBeulich@xxxxxxxx>
  • Date: Fri, 23 Mar 2012 11:01:34 +0000
  • Delivery-date: Fri, 23 Mar 2012 11:01:04 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

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>

--- a/drivers/xen/core/smpboot.c
+++ b/drivers/xen/core/smpboot.c
@@ -146,7 +146,6 @@ static int __cpuinit xen_smp_intr_init(u
        return rc;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 static void xen_smp_intr_exit(unsigned int cpu)
 {
        if (cpu != 0)
@@ -155,7 +154,6 @@ static void xen_smp_intr_exit(unsigned i
        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 @@ void __cpuinit cpu_bringup(void)
        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 @@ int __cpuinit __cpu_up(unsigned int cpu)
        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 @@ int __cpuinit __cpu_up(unsigned int cpu)
        set_cpu_sibling_map(cpu);
        wmb();
 
-       rc = xen_smp_intr_init(cpu);
+       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;
+               }
+       }
+
        if (rc) {
+               xen_smp_intr_exit(cpu);
                remove_siblinginfo(cpu);
-               return rc;
+               if (num_online_cpus() == 1)
+                       alternatives_smp_switch(0);
        }
 
-       cpu_set(cpu, cpu_online_map);
-
-       rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
-       BUG_ON(rc);
-
-       return 0;
+       return rc;
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)



Attachment: xen-smpboot-ordering.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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