On Fri, Jul 27, 2007 at 06:53:23AM -0700, Stephane Eranian wrote: > Ralf, > > Here is take 2. > > [MIPS] add smp_call_function_single (take 2) > > signed-off-by: Stephane Eranian <eranian@xxxxxxxxxx> > signed-off-by: Phil Mucci <mucci@xxxxxxxxxx> > > diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c > index be7362b..d47234c 100644 > --- a/arch/mips/kernel/smp.c > +++ b/arch/mips/kernel/smp.c > @@ -193,6 +193,53 @@ void smp_call_function_interrupt(void) > } > } > > +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry, > + int wait) > +{ > + struct call_data_struct data; > + int me = smp_processor_id(); > + > + /* > + * Can die spectacularly if this CPU isn't yet marked online > + */ > + BUG_ON(!cpu_online(me)); > + if (cpu == me) { > + WARN_ON(1); > + return -EBUSY; > + } > + > + /* Can deadlock when called with interrupts disabled */ > + WARN_ON(irqs_disabled()); > + > + data.func = func; > + data.info = info; > + atomic_set(&data.started, 0); > + data.wait = wait; > + if (wait) > + atomic_set(&data.finished, 0); > + > + spin_lock(&smp_call_lock); > + call_data = &data; > + mb(); > + > + /* Send a message to the other CPU */ > + core_send_ipi(cpu, SMP_CALL_FUNCTION); > + > + /* Wait for response */ > + /* FIXME: lock-up detection, backtrace on lock-up */ > + while (atomic_read(&data.started) != 1) > + barrier(); > + > + if (wait) > + while (atomic_read(&data.finished) != 1) > + barrier(); > + call_data = NULL; > + spin_unlock(&smp_call_lock); > + > + return 0; > +} > +EXPORT_SYMBOL(smp_call_function_single); > + > static void stop_this_cpu(void *dummy) > { This will not do the right thing. Semantics of smp_call_function_single() changed recently. It now is supposed to call func() locally with irqs disabled if cpu == smp_processor_id(). See i386/x86_64 and powerpc. Unfortunately ia64 hasn't been changed yet, so it will behave differently.