ARMv7: Use lazy cache flushing if hardware broadcasts cache operations
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 9 Mar 2010 09:55:10 +0000 (09:55 +0000)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:32:27 +0000 (16:32 -0700)
ARMv7 processors like Cortex-A9 broadcast the cache maintenance
operations in hardware. The patch adds the CPU ID checks for such
feature and allows the flush_dcache_page/update_mmu_cache pair to work
in lazy flushing mode similar to the UP case.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm/include/asm/smp_plat.h
arch/arm/mm/fault-armv.c
arch/arm/mm/flush.c

index e6215305544aa9c63db768c53a7c194fe38c6747..963a338d567bf9d5d82ce29670998c46cb7abfe3 100644 (file)
@@ -13,9 +13,13 @@ static inline int tlb_ops_need_broadcast(void)
        return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
 }
 
+#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
+#define cache_ops_need_broadcast()     0
+#else
 static inline int cache_ops_need_broadcast(void)
 {
        return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
 }
+#endif
 
 #endif
index 9b906dec1ca1abc0ec308472dc39a7684c6c3b01..9d77d90f4adea7393edc1b123401c4214f48be0e 100644 (file)
@@ -168,10 +168,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
                return;
 
        mapping = page_mapping(page);
-#ifndef CONFIG_SMP
        if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
                __flush_dcache_page(mapping, page);
-#endif
        if (mapping) {
                if (cache_is_vivt())
                        make_coherent(mapping, vma, addr, ptep, pfn);
index c6844cb9b508dde69c49af40bb0d2956b126b8d3..e0758968e9f8726dc90564e806774824f7e1798f 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
+#include <asm/smp_plat.h>
 
 #include "mm.h"
 
@@ -246,12 +247,10 @@ void flush_dcache_page(struct page *page)
 
        mapping = page_mapping(page);
 
-#ifndef CONFIG_SMP
-       if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
+       if (!cache_ops_need_broadcast() &&
+           !PageHighMem(page) && mapping && !mapping_mapped(mapping))
                set_bit(PG_dcache_dirty, &page->flags);
-       else
-#endif
-       {
+       else {
                __flush_dcache_page(mapping, page);
                if (mapping && cache_is_vivt())
                        __flush_dcache_aliases(mapping, page);