aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-05-17 11:20:18 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-05-17 11:22:46 -0400
commit826681043d7184b4d650cab5b007b9a86b628eb5 (patch)
tree03b3914863138e88a985d1d4e2e7258ec81378d5 /arch/arm
parent0f6f49a8cd0163fdb1723ed29f01fc65177108dc (diff)
[ARM] smp: fix cpumask usage in ARM SMP code
The ARM SMP code wasn't properly updated for the cpumask changes, which results in smp_timer_broadcast() broadcasting ticks to non-online CPUs. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/common/gic.c4
-rw-r--r--arch/arm/include/asm/hardware/gic.h2
-rw-r--r--arch/arm/include/asm/smp.h12
-rw-r--r--arch/arm/kernel/smp.c46
-rw-r--r--arch/arm/mach-realview/include/mach/smp.h6
-rw-r--r--arch/arm/mach-realview/platsmp.c4
6 files changed, 28 insertions, 46 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index c6884ba1d5ed..3e1714c6523f 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
253} 253}
254 254
255#ifdef CONFIG_SMP 255#ifdef CONFIG_SMP
256void gic_raise_softirq(cpumask_t cpumask, unsigned int irq) 256void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
257{ 257{
258 unsigned long map = *cpus_addr(cpumask); 258 unsigned long map = *cpus_addr(*mask);
259 259
260 /* this always happens on GIC0 */ 260 /* this always happens on GIC0 */
261 writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); 261 writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4924914af188..7f34333bb545 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -36,7 +36,7 @@
36void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); 36void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
37void gic_cpu_init(unsigned int gic_nr, void __iomem *base); 37void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
38void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 38void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
39void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); 39void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
40#endif 40#endif
41 41
42#endif 42#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index fad70da5911d..5995935338e1 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned int cpuid);
53/* 53/*
54 * Raise an IPI cross call on CPUs in callmap. 54 * Raise an IPI cross call on CPUs in callmap.
55 */ 55 */
56extern void smp_cross_call(cpumask_t callmap); 56extern void smp_cross_call(const struct cpumask *mask);
57
58/*
59 * Broadcast a timer interrupt to the other CPUs.
60 */
61extern void smp_send_timer(void);
62 57
63/* 58/*
64 * Broadcast a clock event to other CPUs. 59 * Broadcast a clock event to other CPUs.
65 */ 60 */
66extern void smp_timer_broadcast(cpumask_t mask); 61extern void smp_timer_broadcast(const struct cpumask *mask);
67 62
68/* 63/*
69 * Boot a secondary CPU, and assign it the specified idle task. 64 * Boot a secondary CPU, and assign it the specified idle task.
@@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned int cpu);
102extern void platform_cpu_enable(unsigned int cpu); 97extern void platform_cpu_enable(unsigned int cpu);
103 98
104extern void arch_send_call_function_single_ipi(int cpu); 99extern void arch_send_call_function_single_ipi(int cpu);
105extern void arch_send_call_function_ipi(cpumask_t mask); 100extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
101#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
106 102
107/* 103/*
108 * Local timer interrupt handling function (can be IPI'ed). 104 * Local timer interrupt handling function (can be IPI'ed).
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7801aac3c043..6014dfd22af4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -326,14 +326,14 @@ void __init smp_prepare_boot_cpu(void)
326 per_cpu(cpu_data, cpu).idle = current; 326 per_cpu(cpu_data, cpu).idle = current;
327} 327}
328 328
329static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) 329static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg)
330{ 330{
331 unsigned long flags; 331 unsigned long flags;
332 unsigned int cpu; 332 unsigned int cpu;
333 333
334 local_irq_save(flags); 334 local_irq_save(flags);
335 335
336 for_each_cpu_mask(cpu, callmap) { 336 for_each_cpu(cpu, mask) {
337 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 337 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
338 338
339 spin_lock(&ipi->lock); 339 spin_lock(&ipi->lock);
@@ -344,19 +344,19 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
344 /* 344 /*
345 * Call the platform specific cross-CPU call function. 345 * Call the platform specific cross-CPU call function.
346 */ 346 */
347 smp_cross_call(callmap); 347 smp_cross_call(mask);
348 348
349 local_irq_restore(flags); 349 local_irq_restore(flags);
350} 350}
351 351
352void arch_send_call_function_ipi(cpumask_t mask) 352void arch_send_call_function_ipi_mask(const struct cpumask *mask)
353{ 353{
354 send_ipi_message(mask, IPI_CALL_FUNC); 354 send_ipi_message(mask, IPI_CALL_FUNC);
355} 355}
356 356
357void arch_send_call_function_single_ipi(int cpu) 357void arch_send_call_function_single_ipi(int cpu)
358{ 358{
359 send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE); 359 send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
360} 360}
361 361
362void show_ipi_list(struct seq_file *p) 362void show_ipi_list(struct seq_file *p)
@@ -498,17 +498,10 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs)
498 498
499void smp_send_reschedule(int cpu) 499void smp_send_reschedule(int cpu)
500{ 500{
501 send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); 501 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
502} 502}
503 503
504void smp_send_timer(void) 504void smp_timer_broadcast(const struct cpumask *mask)
505{
506 cpumask_t mask = cpu_online_map;
507 cpu_clear(smp_processor_id(), mask);
508 send_ipi_message(mask, IPI_TIMER);
509}
510
511void smp_timer_broadcast(cpumask_t mask)
512{ 505{
513 send_ipi_message(mask, IPI_TIMER); 506 send_ipi_message(mask, IPI_TIMER);
514} 507}
@@ -517,7 +510,7 @@ void smp_send_stop(void)
517{ 510{
518 cpumask_t mask = cpu_online_map; 511 cpumask_t mask = cpu_online_map;
519 cpu_clear(smp_processor_id(), mask); 512 cpu_clear(smp_processor_id(), mask);
520 send_ipi_message(mask, IPI_CPU_STOP); 513 send_ipi_message(&mask, IPI_CPU_STOP);
521} 514}
522 515
523/* 516/*
@@ -528,20 +521,17 @@ int setup_profiling_timer(unsigned int multiplier)
528 return -EINVAL; 521 return -EINVAL;
529} 522}
530 523
531static int 524static void
532on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask) 525on_each_cpu_mask(void (*func)(void *), void *info, int wait,
526 const struct cpumask *mask)
533{ 527{
534 int ret = 0;
535
536 preempt_disable(); 528 preempt_disable();
537 529
538 ret = smp_call_function_mask(mask, func, info, wait); 530 smp_call_function_many(mask, func, info, wait);
539 if (cpu_isset(smp_processor_id(), mask)) 531 if (cpumask_test_cpu(smp_processor_id(), mask))
540 func(info); 532 func(info);
541 533
542 preempt_enable(); 534 preempt_enable();
543
544 return ret;
545} 535}
546 536
547/**********************************************************************/ 537/**********************************************************************/
@@ -602,20 +592,17 @@ void flush_tlb_all(void)
602 592
603void flush_tlb_mm(struct mm_struct *mm) 593void flush_tlb_mm(struct mm_struct *mm)
604{ 594{
605 cpumask_t mask = mm->cpu_vm_mask; 595 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask);
606
607 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask);
608} 596}
609 597
610void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 598void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
611{ 599{
612 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
613 struct tlb_args ta; 600 struct tlb_args ta;
614 601
615 ta.ta_vma = vma; 602 ta.ta_vma = vma;
616 ta.ta_start = uaddr; 603 ta.ta_start = uaddr;
617 604
618 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); 605 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask);
619} 606}
620 607
621void flush_tlb_kernel_page(unsigned long kaddr) 608void flush_tlb_kernel_page(unsigned long kaddr)
@@ -630,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long kaddr)
630void flush_tlb_range(struct vm_area_struct *vma, 617void flush_tlb_range(struct vm_area_struct *vma,
631 unsigned long start, unsigned long end) 618 unsigned long start, unsigned long end)
632{ 619{
633 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
634 struct tlb_args ta; 620 struct tlb_args ta;
635 621
636 ta.ta_vma = vma; 622 ta.ta_vma = vma;
637 ta.ta_start = start; 623 ta.ta_start = start;
638 ta.ta_end = end; 624 ta.ta_end = end;
639 625
640 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); 626 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask);
641} 627}
642 628
643void flush_tlb_kernel_range(unsigned long start, unsigned long end) 629void flush_tlb_kernel_range(unsigned long start, unsigned long end)
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index 515819efd046..e2ff53402f8c 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -15,15 +15,15 @@
15/* 15/*
16 * We use IRQ1 as the IPI 16 * We use IRQ1 as the IPI
17 */ 17 */
18static inline void smp_cross_call(cpumask_t callmap) 18static inline void smp_cross_call(const struct cpumask *mask)
19{ 19{
20 gic_raise_softirq(callmap, 1); 20 gic_raise_softirq(mask, 1);
21} 21}
22 22
23/* 23/*
24 * Do nothing on MPcore. 24 * Do nothing on MPcore.
25 */ 25 */
26static inline void smp_cross_call_done(cpumask_t callmap) 26static inline void smp_cross_call_done(const struct cpumask *mask)
27{ 27{
28} 28}
29 29
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index ea3c75595fa9..a5730466dff5 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -82,7 +82,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
82 * to get this processor out of WFI in the BootMonitor - make 82 * to get this processor out of WFI in the BootMonitor - make
83 * sure that we are no longer being sent this soft interrupt 83 * sure that we are no longer being sent this soft interrupt
84 */ 84 */
85 smp_cross_call_done(cpumask_of_cpu(cpu)); 85 smp_cross_call_done(cpumask_of(cpu));
86 86
87 /* 87 /*
88 * if any interrupts are already enabled for the primary 88 * if any interrupts are already enabled for the primary
@@ -136,7 +136,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
136 * Use smp_cross_call() for this, since there's little 136 * Use smp_cross_call() for this, since there's little
137 * point duplicating the code here 137 * point duplicating the code here
138 */ 138 */
139 smp_cross_call(cpumask_of_cpu(cpu)); 139 smp_cross_call(cpumask_of(cpu));
140 140
141 timeout = jiffies + (1 * HZ); 141 timeout = jiffies + (1 * HZ);
142 while (time_before(jiffies, timeout)) { 142 while (time_before(jiffies, timeout)) {