[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Do no thold cpu_add_remove_lock across stop_machine_run().
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1273833555 -3600 # Node ID 578375084a9ee1063f4bc5a8e64e59677804cdb9 # Parent 9ff084bae83a1506f731ff6a926fefcccec5b1b1 x86: Do no thold cpu_add_remove_lock across stop_machine_run(). Instead we protect against concurrent online/offline requests for a single CPU asynchronously, using a cpumask for bookkeeping. This means that cpu_add_remove_lock no longer needs to be acquired via spin_trylock. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/platform_hypercall.c | 7 ----- xen/arch/x86/smpboot.c | 49 ++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff -r 9ff084bae83a -r 578375084a9e xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Fri May 14 10:13:30 2010 +0100 +++ b/xen/arch/x86/platform_hypercall.c Fri May 14 11:39:15 2010 +0100 @@ -409,12 +409,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe g_info = &op->u.pcpu_info; - /* spin_trylock() avoids deadlock with stop_machine_run(). */ - if ( !spin_trylock(&cpu_add_remove_lock) ) - { - ret = -EBUSY; - break; - } + spin_lock(&cpu_add_remove_lock); if ( (g_info->xen_cpuid >= NR_CPUS) || (g_info->xen_cpuid < 0) || diff -r 9ff084bae83a -r 578375084a9e xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Fri May 14 10:13:30 2010 +0100 +++ b/xen/arch/x86/smpboot.c Fri May 14 11:39:15 2010 +0100 @@ -1330,24 +1330,25 @@ static int take_cpu_down(void *unused) return __cpu_disable(); } +/* + * Protects against concurrent offline/online requests for a single CPU. + * We need this extra protection because cpu_down() cannot continuously hold + * the cpu_add_remove_lock, as it cannot be held across stop_machine_run(). + */ +static cpumask_t cpu_offlining; + int cpu_down(unsigned int cpu) { int err = 0; - /* spin_trylock() avoids deadlock with stop_machine_run(). */ - if (!spin_trylock(&cpu_add_remove_lock)) - return -EBUSY; - - /* Can not offline BSP */ - if (cpu == 0) { - err = -EINVAL; - goto out; - } - - if (!cpu_online(cpu)) { - err = -EINVAL; - goto out; - } + spin_lock(&cpu_add_remove_lock); + + if ((cpu == 0) || !cpu_online(cpu) || cpu_isset(cpu, cpu_offlining)) { + spin_unlock(&cpu_add_remove_lock); + return -EINVAL; + } + + cpu_set(cpu, cpu_offlining); err = cpupool_cpu_remove(cpu); if (err) @@ -1357,14 +1358,16 @@ int cpu_down(unsigned int cpu) cpufreq_del_cpu(cpu); + spin_unlock(&cpu_add_remove_lock); err = stop_machine_run(take_cpu_down, NULL, cpu); + spin_lock(&cpu_add_remove_lock); + if (err < 0) { cpupool_cpu_add(cpu); goto out; } __cpu_die(cpu); - BUG_ON(cpu_online(cpu)); migrate_tasklets_from_cpu(cpu); @@ -1373,6 +1376,7 @@ out: out: if (!err) send_guest_global_virq(dom0, VIRQ_PCPU_STATE); + cpu_clear(cpu, cpu_offlining); spin_unlock(&cpu_add_remove_lock); return err; } @@ -1381,13 +1385,10 @@ int cpu_up(unsigned int cpu) { int err = 0; - /* spin_trylock() avoids deadlock with stop_machine_run(). */ - if (!spin_trylock(&cpu_add_remove_lock)) - return -EBUSY; - - if (cpu_online(cpu)) { - printk("Bring up a online cpu. Bogus!\n"); - err = -EBUSY; + spin_lock(&cpu_add_remove_lock); + + if (cpu_online(cpu) || cpu_isset(cpu, cpu_offlining)) { + err = -EINVAL; goto out; } @@ -1485,9 +1486,7 @@ int cpu_add(uint32_t apic_id, uint32_t a if ( physid_isset(apic_id, phys_cpu_present_map) ) return -EEXIST; - /* spin_trylock() avoids deadlock with stop_machine_run(). */ - if (!spin_trylock(&cpu_add_remove_lock)) - return -EBUSY; + spin_lock(&cpu_add_remove_lock); cpu = mp_register_lapic(apic_id, 1); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |