diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2013-05-01 07:23:05 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-06-07 12:58:28 -0400 |
commit | b5b6c9e9149d8a7c3f1d7b9d0c046c6184e1dd17 (patch) | |
tree | 820998f37abcb6ab846e9c9ec59ec30c5c0b43f4 /arch/arm64/mm/flush.c | |
parent | d25749afc6f2a40471a70c04a35633e30cbe59a5 (diff) |
arm64: Avoid cache flushing in flush_dcache_page()
The flush_dcache_page() function is called when the kernel modified a
page cache page. Since the D-cache on AArch64 does not have aliases
this function can simply mark the page as dirty for later flushing via
set_pte_at()/__sync_icache_dcache() if the page is executable (to ensure
the I-D cache coherency).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Will Deacon <will.deacon@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/mm/flush.c')
-rw-r--r-- | arch/arm64/mm/flush.c | 22 |
1 files changed, 4 insertions, 18 deletions
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c index 88611c3a421a..b9cd7a4deeca 100644 --- a/arch/arm64/mm/flush.c +++ b/arch/arm64/mm/flush.c | |||
@@ -94,28 +94,14 @@ void __sync_icache_dcache(pte_t pte, unsigned long addr) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Ensure cache coherency between kernel mapping and userspace mapping of this | 97 | * This function is called when a page has been modified by the kernel. Mark |
98 | * page. | 98 | * it as dirty for later flushing when mapped in user space (if executable, |
99 | * see __sync_icache_dcache). | ||
99 | */ | 100 | */ |
100 | void flush_dcache_page(struct page *page) | 101 | void flush_dcache_page(struct page *page) |
101 | { | 102 | { |
102 | struct address_space *mapping; | 103 | if (test_bit(PG_dcache_clean, &page->flags)) |
103 | |||
104 | /* | ||
105 | * The zero page is never written to, so never has any dirty cache | ||
106 | * lines, and therefore never needs to be flushed. | ||
107 | */ | ||
108 | if (page == ZERO_PAGE(0)) | ||
109 | return; | ||
110 | |||
111 | mapping = page_mapping(page); | ||
112 | if (mapping && mapping_mapped(mapping)) { | ||
113 | __flush_dcache_page(page); | ||
114 | __flush_icache_all(); | ||
115 | set_bit(PG_dcache_clean, &page->flags); | ||
116 | } else { | ||
117 | clear_bit(PG_dcache_clean, &page->flags); | 104 | clear_bit(PG_dcache_clean, &page->flags); |
118 | } | ||
119 | } | 105 | } |
120 | EXPORT_SYMBOL(flush_dcache_page); | 106 | EXPORT_SYMBOL(flush_dcache_page); |
121 | 107 | ||