diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2013-04-24 14:41:37 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-04-25 13:15:15 +0100 |
commit | 3eb0be304273054fd2ae34367f96127d082e310c (patch) | |
tree | 27ba3f69ba99409c8bcbb40af5d670cef3082103 /arch/arm/kernel/smp_tlb.c | |
parent | 60d509fa6a9c4653a86ad830e4c4b30360b23f0e (diff) |
ARM: 7703/1: Disable preemption in broadcast_tlb*_a15_erratum()
Commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum
798181 (TLBI/DSB operations)) introduces calls to smp_processor_id() and
smp_call_function_many() with preemption enabled. This patch disables
preemption and also optimises the smp_processor_id() call in
broadcast_tlb_mm_a15_erratum(). The broadcast_tlb_a15_erratum() function
is changed to use smp_call_function() which disables preemption.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Geoff Levand <geoff@infradead.org>
Reported-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/smp_tlb.c')
-rw-r--r-- | arch/arm/kernel/smp_tlb.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index e82e1d24877..9a52a07aa40 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -98,21 +98,21 @@ static void broadcast_tlb_a15_erratum(void) return; dummy_flush_tlb_a15_erratum(); - smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum, - NULL, 1); + smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1); } static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) { - int cpu; + int cpu, this_cpu; cpumask_t mask = { CPU_BITS_NONE }; if (!erratum_a15_798181()) return; dummy_flush_tlb_a15_erratum(); + this_cpu = get_cpu(); for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) + if (cpu == this_cpu) continue; /* * We only need to send an IPI if the other CPUs are running @@ -127,6 +127,7 @@ static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) cpumask_set_cpu(cpu, &mask); } smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); + put_cpu(); } void flush_tlb_all(void) |