diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-11-25 02:29:03 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-12-23 01:35:04 -0500 |
commit | ddf84433f411b612e935a6719ee395bb9dd2221f (patch) | |
tree | d9dab0c2b2b6aa73e1959149e21baf38031dc7ff /arch/arc | |
parent | 413541dd66d51f791a0b169d9b9014e4f56be13c (diff) |
ARC: [SMP] cpumask not needed in IPI send path
The current IPI sending callstack needlessly involves cpumask.
arch_send_call_function_single_ipi(cpu) / smp_send_reschedule(cpu)
ipi_send_msg(cpumask_of(cpu)) --> [cpu to cpumask]
plat_smp_ops.ipi_send(callmap)
for_each_cpu(callmap) --> [cpuask to cpu]
do_plat_specific_ipi_PER_CPU
Given that current backends are not capable of 1:N IPIs, lets simplify
the interface for now, by keeping "a" cpu all along.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/include/asm/smp.h | 4 | ||||
-rw-r--r-- | arch/arc/kernel/smp.c | 23 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/smp.c | 8 |
3 files changed, 18 insertions, 17 deletions
diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index eefc29f08cdb..9b40e3bdc1ba 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h | |||
@@ -46,13 +46,13 @@ extern int smp_ipi_irq_setup(int cpu, int irq); | |||
46 | * | 46 | * |
47 | * @info: SoC SMP specific info for /proc/cpuinfo etc | 47 | * @info: SoC SMP specific info for /proc/cpuinfo etc |
48 | * @cpu_kick: For Master to kickstart a cpu (optionally at a PC) | 48 | * @cpu_kick: For Master to kickstart a cpu (optionally at a PC) |
49 | * @ipi_send: To send IPI to a @cpumask | 49 | * @ipi_send: To send IPI to a @cpu |
50 | * @ips_clear: To clear IPI received by @cpu at @irq | 50 | * @ips_clear: To clear IPI received by @cpu at @irq |
51 | */ | 51 | */ |
52 | struct plat_smp_ops { | 52 | struct plat_smp_ops { |
53 | const char *info; | 53 | const char *info; |
54 | void (*cpu_kick)(int cpu, unsigned long pc); | 54 | void (*cpu_kick)(int cpu, unsigned long pc); |
55 | void (*ipi_send)(void *callmap); | 55 | void (*ipi_send)(int cpu); |
56 | void (*ipi_clear)(int cpu, int irq); | 56 | void (*ipi_clear)(int cpu, int irq); |
57 | }; | 57 | }; |
58 | 58 | ||
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index c2f9ebbc38f6..f2fdef964045 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c | |||
@@ -220,28 +220,33 @@ struct ipi_data { | |||
220 | 220 | ||
221 | static DEFINE_PER_CPU(struct ipi_data, ipi_data); | 221 | static DEFINE_PER_CPU(struct ipi_data, ipi_data); |
222 | 222 | ||
223 | static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg) | 223 | static void ipi_send_msg_one(int cpu, enum ipi_msg_type msg) |
224 | { | 224 | { |
225 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | ||
225 | unsigned long flags; | 226 | unsigned long flags; |
226 | unsigned int cpu; | ||
227 | 227 | ||
228 | local_irq_save(flags); | 228 | local_irq_save(flags); |
229 | 229 | ||
230 | for_each_cpu(cpu, callmap) { | 230 | set_bit(msg, &ipi->bits); |
231 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | ||
232 | set_bit(msg, &ipi->bits); | ||
233 | } | ||
234 | 231 | ||
235 | /* Call the platform specific cross-CPU call function */ | 232 | /* Call the platform specific cross-CPU call function */ |
236 | if (plat_smp_ops.ipi_send) | 233 | if (plat_smp_ops.ipi_send) |
237 | plat_smp_ops.ipi_send((void *)callmap); | 234 | plat_smp_ops.ipi_send(cpu); |
238 | 235 | ||
239 | local_irq_restore(flags); | 236 | local_irq_restore(flags); |
240 | } | 237 | } |
241 | 238 | ||
239 | static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg) | ||
240 | { | ||
241 | unsigned int cpu; | ||
242 | |||
243 | for_each_cpu(cpu, callmap) | ||
244 | ipi_send_msg_one(cpu, msg); | ||
245 | } | ||
246 | |||
242 | void smp_send_reschedule(int cpu) | 247 | void smp_send_reschedule(int cpu) |
243 | { | 248 | { |
244 | ipi_send_msg(cpumask_of(cpu), IPI_RESCHEDULE); | 249 | ipi_send_msg_one(cpu, IPI_RESCHEDULE); |
245 | } | 250 | } |
246 | 251 | ||
247 | void smp_send_stop(void) | 252 | void smp_send_stop(void) |
@@ -254,7 +259,7 @@ void smp_send_stop(void) | |||
254 | 259 | ||
255 | void arch_send_call_function_single_ipi(int cpu) | 260 | void arch_send_call_function_single_ipi(int cpu) |
256 | { | 261 | { |
257 | ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC); | 262 | ipi_send_msg_one(cpu, IPI_CALL_FUNC); |
258 | } | 263 | } |
259 | 264 | ||
260 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) | 265 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
diff --git a/arch/arc/plat-arcfpga/smp.c b/arch/arc/plat-arcfpga/smp.c index 91b55349a5f8..5e4fe959665c 100644 --- a/arch/arc/plat-arcfpga/smp.c +++ b/arch/arc/plat-arcfpga/smp.c | |||
@@ -88,13 +88,9 @@ void iss_model_init_smp(unsigned int cpu) | |||
88 | smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu); | 88 | smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void iss_model_ipi_send(void *arg) | 91 | static void iss_model_ipi_send(int cpu) |
92 | { | 92 | { |
93 | struct cpumask *callmap = arg; | 93 | idu_irq_assert(cpu); |
94 | unsigned int cpu; | ||
95 | |||
96 | for_each_cpu(cpu, callmap) | ||
97 | idu_irq_assert(cpu); | ||
98 | } | 94 | } |
99 | 95 | ||
100 | static void iss_model_ipi_clear(int cpu, int irq) | 96 | static void iss_model_ipi_clear(int cpu, int irq) |