Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MIPS] Add smp_call_function_single()

In the other archs, there is more factoring of smp call code, and more care
in the use of get_cpu(). That can be a follow-up MIPS patch.

Signed-off-by: Peter Watkins <pwatkins@sicortex.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Peter Watkins and committed by
Ralf Baechle
b4b2917c 185bcd17

+55
+55
arch/mips/kernel/smp.c
··· 194 194 } 195 195 } 196 196 197 + int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 198 + int retry, int wait) 199 + { 200 + struct call_data_struct data; 201 + int me; 202 + 203 + /* 204 + * Can die spectacularly if this CPU isn't yet marked online 205 + */ 206 + if (!cpu_online(cpu)) 207 + return 0; 208 + 209 + me = get_cpu(); 210 + BUG_ON(!cpu_online(me)); 211 + 212 + if (cpu == me) { 213 + local_irq_disable(); 214 + func(info); 215 + local_irq_enable(); 216 + put_cpu(); 217 + return 0; 218 + } 219 + 220 + /* Can deadlock when called with interrupts disabled */ 221 + WARN_ON(irqs_disabled()); 222 + 223 + data.func = func; 224 + data.info = info; 225 + atomic_set(&data.started, 0); 226 + data.wait = wait; 227 + if (wait) 228 + atomic_set(&data.finished, 0); 229 + 230 + spin_lock(&smp_call_lock); 231 + call_data = &data; 232 + smp_mb(); 233 + 234 + /* Send a message to the other CPU */ 235 + core_send_ipi(cpu, SMP_CALL_FUNCTION); 236 + 237 + /* Wait for response */ 238 + /* FIXME: lock-up detection, backtrace on lock-up */ 239 + while (atomic_read(&data.started) != 1) 240 + barrier(); 241 + 242 + if (wait) 243 + while (atomic_read(&data.finished) != 1) 244 + barrier(); 245 + call_data = NULL; 246 + spin_unlock(&smp_call_lock); 247 + 248 + put_cpu(); 249 + return 0; 250 + } 251 + 197 252 static void stop_this_cpu(void *dummy) 198 253 { 199 254 /*