diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-10-03 01:24:16 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-10-11 23:46:18 +0100 |
commit | bd6aeeffcc0be716e4d2d1f27fb132741e345cc0 (patch) | |
tree | db8e97d4669856ed85b73b40ba65301346ca4dd1 | |
parent | 9966db25defba4e1dce263246db25237bc24479f (diff) | |
download | talos-obmc-linux-bd6aeeffcc0be716e4d2d1f27fb132741e345cc0.tar.gz talos-obmc-linux-bd6aeeffcc0be716e4d2d1f27fb132741e345cc0.zip |
[MIPS] SMP: Implement smp_call_function_mask().
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/kernel/gdb-stub.c | 10 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 51 | ||||
-rw-r--r-- | include/asm-mips/smp.h | 9 |
3 files changed, 30 insertions, 40 deletions
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c index c33f6f22d86a..bd128fab4b36 100644 --- a/arch/mips/kernel/gdb-stub.c +++ b/arch/mips/kernel/gdb-stub.c @@ -676,15 +676,18 @@ static void kgdb_wait(void *arg) static int kgdb_smp_call_kgdb_wait(void) { #ifdef CONFIG_SMP + cpumask_t mask = cpu_online_map; struct call_data_struct data; - int i, cpus = num_online_cpus() - 1; int cpu = smp_processor_id(); + int cpus; /* * Can die spectacularly if this CPU isn't yet marked online */ BUG_ON(!cpu_online(cpu)); + cpu_clear(cpu, mask); + cpus = cpus_weight(mask); if (!cpus) return 0; @@ -711,10 +714,7 @@ static int kgdb_smp_call_kgdb_wait(void) call_data = &data; mb(); - /* Send a message to all other CPUs and wait for them to respond */ - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i) && i != cpu) - core_send_ipi(i, SMP_CALL_FUNCTION); + core_send_ipi_mask(mask, SMP_CALL_FUNCTION); /* Wait for response */ /* FIXME: lock-up detection, backtrace on lock-up */ diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 500a7ec2880f..481ba5355dcb 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -97,6 +97,8 @@ struct call_data_struct *call_data; /* * Run a function on all other CPUs. + * + * <mask> cpuset_t of all processors to run the function on. * <func> The function to run. This must be fast and non-blocking. * <info> An arbitrary pointer to pass to the function. * <retry> If true, keep retrying until ready. @@ -121,18 +123,20 @@ struct call_data_struct *call_data; * Spin waiting for call_lock * Deadlock Deadlock */ -int smp_call_function (void (*func) (void *info), void *info, int retry, - int wait) +int smp_call_function_mask(cpumask_t mask, void (*func) (void *info), + void *info, int retry, int wait) { struct call_data_struct data; - int i, cpus = num_online_cpus() - 1; int cpu = smp_processor_id(); + int cpus; /* * Can die spectacularly if this CPU isn't yet marked online */ BUG_ON(!cpu_online(cpu)); + cpu_clear(cpu, mask); + cpus = cpus_weight(mask); if (!cpus) return 0; @@ -151,9 +155,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, smp_mb(); /* Send a message to all other CPUs and wait for them to respond */ - for_each_online_cpu(i) - if (i != cpu) - core_send_ipi(i, SMP_CALL_FUNCTION); + core_send_ipi_mask(mask, SMP_CALL_FUNCTION); /* Wait for response */ /* FIXME: lock-up detection, backtrace on lock-up */ @@ -169,6 +171,11 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, return 0; } +int smp_call_function(void (*func) (void *info), void *info, int retry, + int wait) +{ + return smp_call_function_mask(cpu_online_map, func, info, retry, wait); +} void smp_call_function_interrupt(void) { @@ -199,8 +206,7 @@ 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; + int ret, me; /* * Can die spectacularly if this CPU isn't yet marked online @@ -219,33 +225,8 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, return 0; } - /* 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; - smp_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); + ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, retry, + wait); put_cpu(); return 0; diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 13aef6af422c..dc770025a9b0 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -60,6 +60,15 @@ extern cpumask_t phys_cpu_present_map; */ extern void core_send_ipi(int cpu, unsigned int action); +static inline void core_send_ipi_mask(cpumask_t mask, unsigned int action) +{ + unsigned int i; + + for_each_cpu_mask(i, mask) + core_send_ipi(i, action); +} + + /* * Firmware CPU startup hook */ |