diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-26 22:44:50 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:14:06 -0500 |
commit | 7a591cfe4efef8a232e4938d44ae6693b319f6d7 (patch) | |
tree | e6fbdfb34572f768788b773e3ce186e3924ab685 /arch/sparc64/mm | |
parent | 2a3a5f5ddbefde498e87f10924d4bf741c5bf37f (diff) |
[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/sparc64/mm')
-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 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); | |||
188 | #endif | 188 | #endif |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | __inline__ void flush_dcache_page_impl(struct page *page) | 191 | inline void flush_dcache_page_impl(struct page *page) |
192 | { | 192 | { |
193 | BUG_ON(tlb_type == hypervisor); | ||
193 | #ifdef CONFIG_DEBUG_DCFLUSH | 194 | #ifdef CONFIG_DEBUG_DCFLUSH |
194 | atomic_inc(&dcpage_flushes); | 195 | atomic_inc(&dcpage_flushes); |
195 | #endif | 196 | #endif |
@@ -279,29 +280,31 @@ unsigned long _PAGE_SZBITS __read_mostly; | |||
279 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) | 280 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) |
280 | { | 281 | { |
281 | struct mm_struct *mm; | 282 | struct mm_struct *mm; |
282 | struct page *page; | ||
283 | unsigned long pfn; | ||
284 | unsigned long pg_flags; | ||
285 | |||
286 | pfn = pte_pfn(pte); | ||
287 | if (pfn_valid(pfn) && | ||
288 | (page = pfn_to_page(pfn), page_mapping(page)) && | ||
289 | ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { | ||
290 | int cpu = ((pg_flags >> PG_dcache_cpu_shift) & | ||
291 | PG_dcache_cpu_mask); | ||
292 | int this_cpu = get_cpu(); | ||
293 | |||
294 | /* This is just to optimize away some function calls | ||
295 | * in the SMP case. | ||
296 | */ | ||
297 | if (cpu == this_cpu) | ||
298 | flush_dcache_page_impl(page); | ||
299 | else | ||
300 | smp_flush_dcache_page_impl(page, cpu); | ||
301 | 283 | ||
302 | clear_dcache_dirty_cpu(page, cpu); | 284 | if (tlb_type != hypervisor) { |
285 | unsigned long pfn = pte_pfn(pte); | ||
286 | unsigned long pg_flags; | ||
287 | struct page *page; | ||
288 | |||
289 | if (pfn_valid(pfn) && | ||
290 | (page = pfn_to_page(pfn), page_mapping(page)) && | ||
291 | ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { | ||
292 | int cpu = ((pg_flags >> PG_dcache_cpu_shift) & | ||
293 | PG_dcache_cpu_mask); | ||
294 | int this_cpu = get_cpu(); | ||
295 | |||
296 | /* This is just to optimize away some function calls | ||
297 | * in the SMP case. | ||
298 | */ | ||
299 | if (cpu == this_cpu) | ||
300 | flush_dcache_page_impl(page); | ||
301 | else | ||
302 | smp_flush_dcache_page_impl(page, cpu); | ||
303 | |||
304 | clear_dcache_dirty_cpu(page, cpu); | ||
303 | 305 | ||
304 | put_cpu(); | 306 | put_cpu(); |
307 | } | ||
305 | } | 308 | } |
306 | 309 | ||
307 | mm = vma->vm_mm; | 310 | mm = vma->vm_mm; |
@@ -321,6 +324,9 @@ void flush_dcache_page(struct page *page) | |||
321 | struct address_space *mapping; | 324 | struct address_space *mapping; |
322 | int this_cpu; | 325 | int this_cpu; |
323 | 326 | ||
327 | if (tlb_type == hypervisor) | ||
328 | return; | ||
329 | |||
324 | /* Do not bother with the expensive D-cache flush if it | 330 | /* Do not bother with the expensive D-cache flush if it |
325 | * is merely the zero page. The 'bigcore' testcase in GDB | 331 | * is merely the zero page. The 'bigcore' testcase in GDB |
326 | * causes this case to run millions of times. | 332 | * 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 | |||
49 | if (pte_exec(orig)) | 49 | if (pte_exec(orig)) |
50 | vaddr |= 0x1UL; | 50 | vaddr |= 0x1UL; |
51 | 51 | ||
52 | if (pte_dirty(orig)) { | 52 | if (tlb_type != hypervisor && |
53 | pte_dirty(orig)) { | ||
53 | unsigned long paddr, pfn = pte_pfn(orig); | 54 | unsigned long paddr, pfn = pte_pfn(orig); |
54 | struct address_space *mapping; | 55 | struct address_space *mapping; |
55 | struct page *page; | 56 | struct page *page; |