[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |