diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-04-06 16:54:33 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-04-09 22:56:44 -0700 |
commit | aa1d1a0af6022f02fb601508d3feaabafd405299 (patch) | |
tree | ef472a0c4df262b26366eb0d25fa2d03c87a444b /arch | |
parent | 731bbe431f7dbbcbdc5293cfb187a916c375e83b (diff) | |
download | linux-3.10-aa1d1a0af6022f02fb601508d3feaabafd405299.tar.gz linux-3.10-aa1d1a0af6022f02fb601508d3feaabafd405299.tar.bz2 linux-3.10-aa1d1a0af6022f02fb601508d3feaabafd405299.zip |
[SPARC64]: smp_call_function() fixups...
1) Take doc-book function comment from i386 implementation.
2) cacheline align call_lock, taken from powerpc
3) Need memory barrier after setting call_data
4) Remove timeout
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/smp.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 8175a6968c6..eb36f7988ff 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -745,12 +745,21 @@ struct call_data_struct { int wait; }; -static DEFINE_SPINLOCK(call_lock); +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); static struct call_data_struct *call_data; extern unsigned long xcall_call_function; -/* +/** + * smp_call_function(): Run a function on all other CPUs. + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: currently unused. + * @wait: If true, wait (atomically) until function has completed on other CPUs. + * + * Returns 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <<func>> or are or have executed. + * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ @@ -759,7 +768,6 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, { struct call_data_struct data; int cpus; - long timeout; /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -777,31 +785,18 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, goto out_unlock; call_data = &data; + mb(); smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); - /* - * Wait for other cpus to complete function or at - * least snap the call data. - */ - timeout = 1000000; - while (atomic_read(&data.finished) != cpus) { - if (--timeout <= 0) - goto out_timeout; - barrier(); - udelay(1); - } + /* Wait for response */ + while (atomic_read(&data.finished) != cpus) + cpu_relax(); out_unlock: spin_unlock(&call_lock); return 0; - -out_timeout: - spin_unlock(&call_lock); - printk("XCALL: Remote cpus not responding, ncpus=%d finished=%d\n", - cpus, atomic_read(&data.finished)); - return 0; } int smp_call_function(void (*func)(void *info), void *info, |