diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-05 01:18:40 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-05 01:18:40 +0200 |
commit | c02a5119e862dea9a1361182840d41ae1fe24227 (patch) | |
tree | 1288c808120dee67538a539352c1aa6875578618 /arch/sparc64/kernel/smp.c | |
parent | sparc64: Make all xcall_deliver's go through common helper function. (diff) | |
download | linux-c02a5119e862dea9a1361182840d41ae1fe24227.tar.xz linux-c02a5119e862dea9a1361182840d41ae1fe24227.zip |
sparc64: Disable local interrupts around xcall_deliver_impl() invocation.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | arch/sparc64/kernel/smp.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 20f4e291c74a..6d458b35643c 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -611,7 +611,7 @@ retry: static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, const cpumask_t *mask) { int cnt, retries, this_cpu, prev_sent, i; - unsigned long flags, status; + unsigned long status; cpumask_t error_mask; struct trap_per_cpu *tb; u16 *cpu_list; @@ -620,18 +620,6 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, const cpum if (cpus_empty(*mask)) return; - /* We have to do this whole thing with interrupts fully disabled. - * Otherwise if we send an xcall from interrupt context it will - * corrupt both our mondo block and cpu list state. - * - * One consequence of this is that we cannot use timeout mechanisms - * that depend upon interrupts being delivered locally. So, for - * example, we cannot sample jiffies and expect it to advance. - * - * Fortunately, udelay() uses %stick/%tick so we can use that. - */ - local_irq_save(flags); - this_cpu = smp_processor_id(); tb = &trap_block[this_cpu]; @@ -720,8 +708,6 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, const cpum } } while (1); - local_irq_restore(flags); - if (unlikely(!cpus_empty(error_mask))) goto fatal_mondo_cpu_error; @@ -738,14 +724,12 @@ fatal_mondo_cpu_error: return; fatal_mondo_timeout: - local_irq_restore(flags); printk(KERN_CRIT "CPU[%d]: SUN4V mondo timeout, no forward " " progress after %d retries.\n", this_cpu, retries); goto dump_cpu_list_and_out; fatal_mondo_error: - local_irq_restore(flags); printk(KERN_CRIT "CPU[%d]: Unexpected SUN4V mondo error %lu\n", this_cpu, status); printk(KERN_CRIT "CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) " @@ -763,7 +747,21 @@ static void (*xcall_deliver_impl)(u64, u64, u64, const cpumask_t *); static void xcall_deliver(u64 data0, u64 data1, u64 data2, const cpumask_t *mask) { + unsigned long flags; + + /* We have to do this whole thing with interrupts fully disabled. + * Otherwise if we send an xcall from interrupt context it will + * corrupt both our mondo block and cpu list state. + * + * One consequence of this is that we cannot use timeout mechanisms + * that depend upon interrupts being delivered locally. So, for + * example, we cannot sample jiffies and expect it to advance. + * + * Fortunately, udelay() uses %stick/%tick so we can use that. + */ + local_irq_save(flags); xcall_deliver_impl(data0, data1, data2, mask); + local_irq_restore(flags); } /* Send cross call to all processors mentioned in MASK_P |