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

[MIPS] SMP: Implement smp_call_function_mask().

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+30 -40
+5 -5
arch/mips/kernel/gdb-stub.c
··· 676 676 static int kgdb_smp_call_kgdb_wait(void) 677 677 { 678 678 #ifdef CONFIG_SMP 679 + cpumask_t mask = cpu_online_map; 679 680 struct call_data_struct data; 680 - int i, cpus = num_online_cpus() - 1; 681 681 int cpu = smp_processor_id(); 682 + int cpus; 682 683 683 684 /* 684 685 * Can die spectacularly if this CPU isn't yet marked online 685 686 */ 686 687 BUG_ON(!cpu_online(cpu)); 687 688 689 + cpu_clear(cpu, mask); 690 + cpus = cpus_weight(mask); 688 691 if (!cpus) 689 692 return 0; 690 693 ··· 714 711 call_data = &data; 715 712 mb(); 716 713 717 - /* Send a message to all other CPUs and wait for them to respond */ 718 - for (i = 0; i < NR_CPUS; i++) 719 - if (cpu_online(i) && i != cpu) 720 - core_send_ipi(i, SMP_CALL_FUNCTION); 714 + core_send_ipi_mask(mask, SMP_CALL_FUNCTION); 721 715 722 716 /* Wait for response */ 723 717 /* FIXME: lock-up detection, backtrace on lock-up */
+16 -35
arch/mips/kernel/smp.c
··· 97 97 98 98 /* 99 99 * Run a function on all other CPUs. 100 + * 101 + * <mask> cpuset_t of all processors to run the function on. 100 102 * <func> The function to run. This must be fast and non-blocking. 101 103 * <info> An arbitrary pointer to pass to the function. 102 104 * <retry> If true, keep retrying until ready. ··· 123 121 * Spin waiting for call_lock 124 122 * Deadlock Deadlock 125 123 */ 126 - int smp_call_function (void (*func) (void *info), void *info, int retry, 127 - int wait) 124 + int smp_call_function_mask(cpumask_t mask, void (*func) (void *info), 125 + void *info, int retry, int wait) 128 126 { 129 127 struct call_data_struct data; 130 - int i, cpus = num_online_cpus() - 1; 131 128 int cpu = smp_processor_id(); 129 + int cpus; 132 130 133 131 /* 134 132 * Can die spectacularly if this CPU isn't yet marked online 135 133 */ 136 134 BUG_ON(!cpu_online(cpu)); 137 135 136 + cpu_clear(cpu, mask); 137 + cpus = cpus_weight(mask); 138 138 if (!cpus) 139 139 return 0; 140 140 ··· 155 151 smp_mb(); 156 152 157 153 /* Send a message to all other CPUs and wait for them to respond */ 158 - for_each_online_cpu(i) 159 - if (i != cpu) 160 - core_send_ipi(i, SMP_CALL_FUNCTION); 154 + core_send_ipi_mask(mask, SMP_CALL_FUNCTION); 161 155 162 156 /* Wait for response */ 163 157 /* FIXME: lock-up detection, backtrace on lock-up */ ··· 171 169 return 0; 172 170 } 173 171 172 + int smp_call_function(void (*func) (void *info), void *info, int retry, 173 + int wait) 174 + { 175 + return smp_call_function_mask(cpu_online_map, func, info, retry, wait); 176 + } 174 177 175 178 void smp_call_function_interrupt(void) 176 179 { ··· 206 199 int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 207 200 int retry, int wait) 208 201 { 209 - struct call_data_struct data; 210 - int me; 202 + int ret, me; 211 203 212 204 /* 213 205 * Can die spectacularly if this CPU isn't yet marked online ··· 225 219 return 0; 226 220 } 227 221 228 - /* Can deadlock when called with interrupts disabled */ 229 - WARN_ON(irqs_disabled()); 230 - 231 - data.func = func; 232 - data.info = info; 233 - atomic_set(&data.started, 0); 234 - data.wait = wait; 235 - if (wait) 236 - atomic_set(&data.finished, 0); 237 - 238 - spin_lock(&smp_call_lock); 239 - call_data = &data; 240 - smp_mb(); 241 - 242 - /* Send a message to the other CPU */ 243 - core_send_ipi(cpu, SMP_CALL_FUNCTION); 244 - 245 - /* Wait for response */ 246 - /* FIXME: lock-up detection, backtrace on lock-up */ 247 - while (atomic_read(&data.started) != 1) 248 - barrier(); 249 - 250 - if (wait) 251 - while (atomic_read(&data.finished) != 1) 252 - barrier(); 253 - call_data = NULL; 254 - spin_unlock(&smp_call_lock); 222 + ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, retry, 223 + wait); 255 224 256 225 put_cpu(); 257 226 return 0;
+9
include/asm-mips/smp.h
··· 60 60 */ 61 61 extern void core_send_ipi(int cpu, unsigned int action); 62 62 63 + static 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 73 * Firmware CPU startup hook 65 74 */