aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-10-02 20:24:16 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-10-11 18:46:18 -0400
commitbd6aeeffcc0be716e4d2d1f27fb132741e345cc0 (patch)
treedb8e97d4669856ed85b73b40ba65301346ca4dd1
parent9966db25defba4e1dce263246db25237bc24479f (diff)
[MIPS] SMP: Implement smp_call_function_mask().
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/gdb-stub.c10
-rw-r--r--arch/mips/kernel/smp.c51
-rw-r--r--include/asm-mips/smp.h9
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)
676static int kgdb_smp_call_kgdb_wait(void) 676static int kgdb_smp_call_kgdb_wait(void)
677{ 677{
678#ifdef CONFIG_SMP 678#ifdef CONFIG_SMP
679 cpumask_t mask = cpu_online_map;
679 struct call_data_struct data; 680 struct call_data_struct data;
680 int i, cpus = num_online_cpus() - 1;
681 int cpu = smp_processor_id(); 681 int cpu = smp_processor_id();
682 int cpus;
682 683
683 /* 684 /*
684 * Can die spectacularly if this CPU isn't yet marked online 685 * Can die spectacularly if this CPU isn't yet marked online
685 */ 686 */
686 BUG_ON(!cpu_online(cpu)); 687 BUG_ON(!cpu_online(cpu));
687 688
689 cpu_clear(cpu, mask);
690 cpus = cpus_weight(mask);
688 if (!cpus) 691 if (!cpus)
689 return 0; 692 return 0;
690 693
@@ -711,10 +714,7 @@ static int kgdb_smp_call_kgdb_wait(void)
711 call_data = &data; 714 call_data = &data;
712 mb(); 715 mb();
713 716
714 /* Send a message to all other CPUs and wait for them to respond */ 717 core_send_ipi_mask(mask, SMP_CALL_FUNCTION);
715 for (i = 0; i < NR_CPUS; i++)
716 if (cpu_online(i) && i != cpu)
717 core_send_ipi(i, SMP_CALL_FUNCTION);
718 718
719 /* Wait for response */ 719 /* Wait for response */
720 /* FIXME: lock-up detection, backtrace on lock-up */ 720 /* 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;
97 97
98/* 98/*
99 * Run a function on all other CPUs. 99 * Run a function on all other CPUs.
100 *
101 * <mask> cpuset_t of all processors to run the function on.
100 * <func> The function to run. This must be fast and non-blocking. 102 * <func> The function to run. This must be fast and non-blocking.
101 * <info> An arbitrary pointer to pass to the function. 103 * <info> An arbitrary pointer to pass to the function.
102 * <retry> If true, keep retrying until ready. 104 * <retry> If true, keep retrying until ready.
@@ -121,18 +123,20 @@ struct call_data_struct *call_data;
121 * Spin waiting for call_lock 123 * Spin waiting for call_lock
122 * Deadlock Deadlock 124 * Deadlock Deadlock
123 */ 125 */
124int smp_call_function (void (*func) (void *info), void *info, int retry, 126int smp_call_function_mask(cpumask_t mask, void (*func) (void *info),
125 int wait) 127 void *info, int retry, int wait)
126{ 128{
127 struct call_data_struct data; 129 struct call_data_struct data;
128 int i, cpus = num_online_cpus() - 1;
129 int cpu = smp_processor_id(); 130 int cpu = smp_processor_id();
131 int cpus;
130 132
131 /* 133 /*
132 * Can die spectacularly if this CPU isn't yet marked online 134 * Can die spectacularly if this CPU isn't yet marked online
133 */ 135 */
134 BUG_ON(!cpu_online(cpu)); 136 BUG_ON(!cpu_online(cpu));
135 137
138 cpu_clear(cpu, mask);
139 cpus = cpus_weight(mask);
136 if (!cpus) 140 if (!cpus)
137 return 0; 141 return 0;
138 142
@@ -151,9 +155,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
151 smp_mb(); 155 smp_mb();
152 156
153 /* Send a message to all other CPUs and wait for them to respond */ 157 /* Send a message to all other CPUs and wait for them to respond */
154 for_each_online_cpu(i) 158 core_send_ipi_mask(mask, SMP_CALL_FUNCTION);
155 if (i != cpu)
156 core_send_ipi(i, SMP_CALL_FUNCTION);
157 159
158 /* Wait for response */ 160 /* Wait for response */
159 /* FIXME: lock-up detection, backtrace on lock-up */ 161 /* FIXME: lock-up detection, backtrace on lock-up */
@@ -169,6 +171,11 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
169 return 0; 171 return 0;
170} 172}
171 173
174int smp_call_function(void (*func) (void *info), void *info, int retry,
175 int wait)
176{
177 return smp_call_function_mask(cpu_online_map, func, info, retry, wait);
178}
172 179
173void smp_call_function_interrupt(void) 180void smp_call_function_interrupt(void)
174{ 181{
@@ -199,8 +206,7 @@ void smp_call_function_interrupt(void)
199int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 206int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
200 int retry, int wait) 207 int retry, int wait)
201{ 208{
202 struct call_data_struct data; 209 int ret, me;
203 int me;
204 210
205 /* 211 /*
206 * Can die spectacularly if this CPU isn't yet marked online 212 * 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,
219 return 0; 225 return 0;
220 } 226 }
221 227
222 /* Can deadlock when called with interrupts disabled */ 228 ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, retry,
223 WARN_ON(irqs_disabled()); 229 wait);
224
225 data.func = func;
226 data.info = info;
227 atomic_set(&data.started, 0);
228 data.wait = wait;
229 if (wait)
230 atomic_set(&data.finished, 0);
231
232 spin_lock(&smp_call_lock);
233 call_data = &data;
234 smp_mb();
235
236 /* Send a message to the other CPU */
237 core_send_ipi(cpu, SMP_CALL_FUNCTION);
238
239 /* Wait for response */
240 /* FIXME: lock-up detection, backtrace on lock-up */
241 while (atomic_read(&data.started) != 1)
242 barrier();
243
244 if (wait)
245 while (atomic_read(&data.finished) != 1)
246 barrier();
247 call_data = NULL;
248 spin_unlock(&smp_call_lock);
249 230
250 put_cpu(); 231 put_cpu();
251 return 0; 232 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;
60 */ 60 */
61extern void core_send_ipi(int cpu, unsigned int action); 61extern void core_send_ipi(int cpu, unsigned int action);
62 62
63static inline void core_send_ipi_mask(cpumask_t mask, unsigned int action)
64{
65 unsigned int i;
66
67 for_each_cpu_mask(i, mask)
68 core_send_ipi(i, action);
69}
70
71
63/* 72/*
64 * Firmware CPU startup hook 73 * Firmware CPU startup hook
65 */ 74 */