diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-26 19:44:50 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 01:14:06 -0800 |
commit | 7a591cfe4efef8a232e4938d44ae6693b319f6d7 (patch) | |
tree | e6fbdfb34572f768788b773e3ce186e3924ab685 | |
parent | 2a3a5f5ddbefde498e87f10924d4bf741c5bf37f (diff) | |
download | op-kernel-dev-7a591cfe4efef8a232e4938d44ae6693b319f6d7.zip op-kernel-dev-7a591cfe4efef8a232e4938d44ae6693b319f6d7.tar.gz |
[SPARC64]: Avoid dcache-dirty page state management on sun4v.
It is totally wasted work, since we have no D-cache aliasing
issues on sun4v.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/mm/init.c | 50 | ||||
-rw-r--r-- | arch/sparc64/mm/tlb.c | 3 |
2 files changed, 30 insertions, 23 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index ccf083a..87d5d1a 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -188,8 +188,9 @@ atomic_t dcpage_flushes_xcall = ATOMIC_INIT(0); #endif #endif -__inline__ void flush_dcache_page_impl(struct page *page) +inline void flush_dcache_page_impl(struct page *page) { + BUG_ON(tlb_type == hypervisor); #ifdef CONFIG_DEBUG_DCFLUSH atomic_inc(&dcpage_flushes); #endif @@ -279,29 +280,31 @@ unsigned long _PAGE_SZBITS __read_mostly; void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) { struct mm_struct *mm; - struct page *page; - unsigned long pfn; - unsigned long pg_flags; - - pfn = pte_pfn(pte); - if (pfn_valid(pfn) && - (page = pfn_to_page(pfn), page_mapping(page)) && - ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { - int cpu = ((pg_flags >> PG_dcache_cpu_shift) & - PG_dcache_cpu_mask); - int this_cpu = get_cpu(); - - /* This is just to optimize away some function calls - * in the SMP case. - */ - if (cpu == this_cpu) - flush_dcache_page_impl(page); - else - smp_flush_dcache_page_impl(page, cpu); - clear_dcache_dirty_cpu(page, cpu); + if (tlb_type != hypervisor) { + unsigned long pfn = pte_pfn(pte); + unsigned long pg_flags; + struct page *page; + + if (pfn_valid(pfn) && + (page = pfn_to_page(pfn), page_mapping(page)) && + ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { + int cpu = ((pg_flags >> PG_dcache_cpu_shift) & + PG_dcache_cpu_mask); + int this_cpu = get_cpu(); + + /* This is just to optimize away some function calls + * in the SMP case. + */ + if (cpu == this_cpu) + flush_dcache_page_impl(page); + else + smp_flush_dcache_page_impl(page, cpu); + + clear_dcache_dirty_cpu(page, cpu); - put_cpu(); + put_cpu(); + } } mm = vma->vm_mm; @@ -321,6 +324,9 @@ void flush_dcache_page(struct page *page) struct address_space *mapping; int this_cpu; + if (tlb_type == hypervisor) + return; + /* 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. diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c index 78357cc..a079cf42 100644 --- a/arch/sparc64/mm/tlb.c +++ b/arch/sparc64/mm/tlb.c @@ -49,7 +49,8 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t if (pte_exec(orig)) vaddr |= 0x1UL; - if (pte_dirty(orig)) { + if (tlb_type != hypervisor && + pte_dirty(orig)) { unsigned long paddr, pfn = pte_pfn(orig); struct address_space *mapping; struct page *page; |