summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-26 19:44:50 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 01:14:06 -0800
commit7a591cfe4efef8a232e4938d44ae6693b319f6d7 (patch)
treee6fbdfb34572f768788b773e3ce186e3924ab685 /arch
parent2a3a5f5ddbefde498e87f10924d4bf741c5bf37f (diff)
downloadlinux-7a591cfe4efef8a232e4938d44ae6693b319f6d7.tar.bz2
[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>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/mm/init.c50
-rw-r--r--arch/sparc64/mm/tlb.c3
2 files changed, 30 insertions, 23 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index ccf083aecb65..87d5d1af1adb 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 78357cc2a0b7..a079cf42505e 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;