ARM: 7703/1: Disable preemption in broadcast_tlb*_a15_erratum()
authorCatalin Marinas <catalin.marinas@arm.com>
Wed, 24 Apr 2013 13:41:37 +0000 (14:41 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 25 Apr 2013 12:15:15 +0000 (13:15 +0100)
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>
arch/arm/kernel/smp_tlb.c

index e82e1d24877227ba65ab716dc6c87e110617bd79..9a52a07aa40ee3c017c55b5b5cce3b92ae7c599c 100644 (file)
@@ -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)