aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/flush.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2010-09-13 10:58:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-09-19 07:17:45 -0400
commit85848dd7ab75fce1134856228582a8df522c91d9 (patch)
tree3b5f34bf871e983d30fad787c098e6d778d962bd /arch/arm/mm/flush.c
parent6012191aa9c6ffff3a23b81162298318b56d7cb3 (diff)
ARM: 6381/1: Use lazy cache flushing on ARMv7 SMP systems
ARMv7 processors like Cortex-A9 broadcast the cache maintenance operations in hardware. This patch allows the flush_dcache_page/update_mmu_cache pair to work in lazy flushing mode similar to the UP case. Note that cache flushing on SMP systems now takes place via the set_pte_at() call (__sync_icache_dcache) and there is no race with other CPUs executing code from the new PTE before the cache flushing took place. Tested-by: Rabin Vincent <rabin.vincent@stericsson.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/flush.c')
-rw-r--r--arch/arm/mm/flush.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index dd5b0120b92e..2332b774c6b9 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -17,6 +17,7 @@
17#include <asm/smp_plat.h> 17#include <asm/smp_plat.h>
18#include <asm/system.h> 18#include <asm/system.h>
19#include <asm/tlbflush.h> 19#include <asm/tlbflush.h>
20#include <asm/smp_plat.h>
20 21
21#include "mm.h" 22#include "mm.h"
22 23
@@ -93,12 +94,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
93#define flush_pfn_alias(pfn,vaddr) do { } while (0) 94#define flush_pfn_alias(pfn,vaddr) do { } while (0)
94#endif 95#endif
95 96
96#ifdef CONFIG_SMP
97static void flush_ptrace_access_other(void *args) 97static void flush_ptrace_access_other(void *args)
98{ 98{
99 __flush_icache_all(); 99 __flush_icache_all();
100} 100}
101#endif
102 101
103static 102static
104void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, 103void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
@@ -122,11 +121,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
122 if (vma->vm_flags & VM_EXEC) { 121 if (vma->vm_flags & VM_EXEC) {
123 unsigned long addr = (unsigned long)kaddr; 122 unsigned long addr = (unsigned long)kaddr;
124 __cpuc_coherent_kern_range(addr, addr + len); 123 __cpuc_coherent_kern_range(addr, addr + len);
125#ifdef CONFIG_SMP
126 if (cache_ops_need_broadcast()) 124 if (cache_ops_need_broadcast())
127 smp_call_function(flush_ptrace_access_other, 125 smp_call_function(flush_ptrace_access_other,
128 NULL, 1); 126 NULL, 1);
129#endif
130 } 127 }
131} 128}
132 129
@@ -276,12 +273,10 @@ void flush_dcache_page(struct page *page)
276 273
277 mapping = page_mapping(page); 274 mapping = page_mapping(page);
278 275
279#ifndef CONFIG_SMP 276 if (!cache_ops_need_broadcast() &&
280 if (mapping && !mapping_mapped(mapping)) 277 mapping && !mapping_mapped(mapping))
281 clear_bit(PG_dcache_clean, &page->flags); 278 clear_bit(PG_dcache_clean, &page->flags);
282 else 279 else {
283#endif
284 {
285 __flush_dcache_page(mapping, page); 280 __flush_dcache_page(mapping, page);
286 if (mapping && cache_is_vivt()) 281 if (mapping && cache_is_vivt())
287 __flush_dcache_aliases(mapping, page); 282 __flush_dcache_aliases(mapping, page);