diff options
author | David S. Miller | 2005-04-17 18:03:09 -0700 |
---|---|---|
committer | Linus Torvalds | 2005-04-17 18:03:09 -0700 |
commit | a9546f59e90d6ec1b65952c547302e0678e3a5ac (patch) | |
tree | d3660490ac539970b875a49c9032c5c946282cbf | |
parent | a4e884a311893b476893739901bed382cd62b4fe (diff) |
[PATCH] sparc64: Do not flush dcache for ZERO_PAGE.
This case actually can get exercised a lot during an ELF
coredump of a process which contains a lot of non-COW'd
anonymous pages. GDB has this test case which in partiaular
creates near terabyte process full of ZERO_PAGEes. It takes
forever to just walk through the page tables because of
all of these spurious cache flushes on sparc64.
With this change it takes only a second or so.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/sparc64/mm/init.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 89022ccaa75b..db6fa77b4dab 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -201,13 +201,24 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p void flush_dcache_page(struct page *page) { - struct address_space *mapping = page_mapping(page); - int dirty = test_bit(PG_dcache_dirty, &page->flags); - int dirty_cpu = dcache_dirty_cpu(page); - int this_cpu = get_cpu(); + struct address_space *mapping; + int this_cpu; + /* Do not bother with the expensive D-cache flush if it + * is merely the zero page. The 'bigcore' testcase in GDB + * causes this case to run millions of times. + */ + if (page == ZERO_PAGE(0)) + return; + + this_cpu = get_cpu(); + + mapping = page_mapping(page); if (mapping && !mapping_mapped(mapping)) { + int dirty = test_bit(PG_dcache_dirty, &page->flags); if (dirty) { + int dirty_cpu = dcache_dirty_cpu(page); + if (dirty_cpu == this_cpu) goto out; smp_flush_dcache_page_impl(page, dirty_cpu); |