aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-08-12 11:40:08 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-09-27 08:37:34 -0400
commit585fa72493edd7d5acb308806e7bb609412c6228 (patch)
tree5ba44983f09c477a35381b1171f58596b7d1110e /arch/mips/mm
parent13fdd31abec5f48cf97693bd14d2e11e0779b4ca (diff)
[MIPS] Retire flush_icache_page from mm use.
On the 34K the redundant cache operations were causing excessive stalls resulting in realtime code running on the second VPE missing its deadline. For all other platforms this patch is just a significant performance improvment as illustrated by below benchmark numbers. Processor, Processes - times in microseconds - smaller is better ------------------------------------------------------------------------------ Host OS Mhz null null open slct sig sig fork exec sh call I/O stat clos TCP inst hndl proc proc proc --------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 25Kf 2.6.18-rc4 533 0.49 1.16 7.57 33.4 30.5 1.34 12.4 5497 17.K 54.K 25Kf 2.6.18-rc4-p 533 0.49 1.16 6.68 23.0 30.7 1.36 8.55 5030 16.K 48.K 4Kc 2.6.18-rc4 80 4.21 15.0 131. 289. 261. 16.5 258. 18.K 70.K 227K 4Kc 2.6.18-rc4-p 80 4.34 13.1 128. 285. 262. 18.2 258. 12.K 52.K 176K 34Kc 2.6.18-rc4 40 5.01 14.0 61.6 90.0 477. 17.9 94.7 29.K 108K 342K 34Kc 2.6.18-rc4-p 40 4.98 13.9 61.2 89.7 475. 17.6 93.7 8758 44.K 158K BCM1480 2.6.18-rc4 700 0.28 0.60 3.68 5.92 16.0 0.78 5.08 931. 3163 15.K BCM1480 2.6.18-rc4-p 700 0.28 0.61 3.65 5.85 16.0 0.79 5.20 395. 1464 8385 TX49-16K 2.6.18-rc3 197 0.73 2.41 19.0 37.8 82.9 2.94 17.5 4438 14.K 56.K TX49-16K 2.6.18-rc3-p 197 0.73 2.40 19.9 36.3 82.9 2.94 23.4 2577 9103 38.K TX49-32K 2.6.18-rc3 396 0.36 1.19 6.80 11.8 41.0 1.46 8.17 2738 8465 32.K TX49-32K 2.6.18-rc3-p 396 0.36 1.19 6.82 10.2 41.0 1.46 8.18 1330 4638 18.K Original patch by me with enhancements by Atsushi Nemoto. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-r3k.c2
-rw-r--r--arch/mips/mm/c-r4k.c2
-rw-r--r--arch/mips/mm/c-sb1.c2
-rw-r--r--arch/mips/mm/c-tx39.c4
-rw-r--r--arch/mips/mm/cache.c18
5 files changed, 15 insertions, 13 deletions
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index bb041a22f20a..e1f35ef81145 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -335,7 +335,7 @@ void __init r3k_cache_init(void)
335 flush_cache_mm = r3k_flush_cache_mm; 335 flush_cache_mm = r3k_flush_cache_mm;
336 flush_cache_range = r3k_flush_cache_range; 336 flush_cache_range = r3k_flush_cache_range;
337 flush_cache_page = r3k_flush_cache_page; 337 flush_cache_page = r3k_flush_cache_page;
338 flush_icache_page = r3k_flush_icache_page; 338 __flush_icache_page = r3k_flush_icache_page;
339 flush_icache_range = r3k_flush_icache_range; 339 flush_icache_range = r3k_flush_icache_range;
340 340
341 flush_cache_sigtramp = r3k_flush_cache_sigtramp; 341 flush_cache_sigtramp = r3k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index b3ccb8738d29..4e1498246343 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1291,7 +1291,7 @@ void __init r4k_cache_init(void)
1291 __flush_cache_all = r4k___flush_cache_all; 1291 __flush_cache_all = r4k___flush_cache_all;
1292 flush_cache_mm = r4k_flush_cache_mm; 1292 flush_cache_mm = r4k_flush_cache_mm;
1293 flush_cache_page = r4k_flush_cache_page; 1293 flush_cache_page = r4k_flush_cache_page;
1294 flush_icache_page = r4k_flush_icache_page; 1294 __flush_icache_page = r4k_flush_icache_page;
1295 flush_cache_range = r4k_flush_cache_range; 1295 flush_cache_range = r4k_flush_cache_range;
1296 1296
1297 flush_cache_sigtramp = r4k_flush_cache_sigtramp; 1297 flush_cache_sigtramp = r4k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 2d71efb82ac5..4bd9ad8a5e07 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -520,7 +520,7 @@ void sb1_cache_init(void)
520 520
521 /* These routines are for Icache coherence with the Dcache */ 521 /* These routines are for Icache coherence with the Dcache */
522 flush_icache_range = sb1_flush_icache_range; 522 flush_icache_range = sb1_flush_icache_range;
523 flush_icache_page = sb1_flush_icache_page; 523 __flush_icache_page = sb1_flush_icache_page;
524 flush_icache_all = __sb1_flush_icache_all; /* local only */ 524 flush_icache_all = __sb1_flush_icache_all; /* local only */
525 525
526 /* This implies an Icache flush too, so can't be nop'ed */ 526 /* This implies an Icache flush too, so can't be nop'ed */
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 5dfc9b1901f6..932a09d7ef84 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -382,7 +382,7 @@ void __init tx39_cache_init(void)
382 flush_cache_mm = (void *) tx39h_flush_icache_all; 382 flush_cache_mm = (void *) tx39h_flush_icache_all;
383 flush_cache_range = (void *) tx39h_flush_icache_all; 383 flush_cache_range = (void *) tx39h_flush_icache_all;
384 flush_cache_page = (void *) tx39h_flush_icache_all; 384 flush_cache_page = (void *) tx39h_flush_icache_all;
385 flush_icache_page = (void *) tx39h_flush_icache_all; 385 __flush_icache_page = (void *) tx39h_flush_icache_all;
386 flush_icache_range = (void *) tx39h_flush_icache_all; 386 flush_icache_range = (void *) tx39h_flush_icache_all;
387 387
388 flush_cache_sigtramp = (void *) tx39h_flush_icache_all; 388 flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
@@ -408,7 +408,7 @@ void __init tx39_cache_init(void)
408 flush_cache_mm = tx39_flush_cache_mm; 408 flush_cache_mm = tx39_flush_cache_mm;
409 flush_cache_range = tx39_flush_cache_range; 409 flush_cache_range = tx39_flush_cache_range;
410 flush_cache_page = tx39_flush_cache_page; 410 flush_cache_page = tx39_flush_cache_page;
411 flush_icache_page = tx39_flush_icache_page; 411 __flush_icache_page = tx39_flush_icache_page;
412 flush_icache_range = tx39_flush_icache_range; 412 flush_icache_range = tx39_flush_icache_range;
413 413
414 flush_cache_sigtramp = tx39_flush_cache_sigtramp; 414 flush_cache_sigtramp = tx39_flush_cache_sigtramp;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index ddd3a2de1d73..40c8b0235183 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -25,7 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
25void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, 25void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
26 unsigned long pfn); 26 unsigned long pfn);
27void (*flush_icache_range)(unsigned long start, unsigned long end); 27void (*flush_icache_range)(unsigned long start, unsigned long end);
28void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); 28void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
29 29
30/* MIPS specific cache operations */ 30/* MIPS specific cache operations */
31void (*flush_cache_sigtramp)(unsigned long addr); 31void (*flush_cache_sigtramp)(unsigned long addr);
@@ -70,6 +70,8 @@ void __flush_dcache_page(struct page *page)
70 struct address_space *mapping = page_mapping(page); 70 struct address_space *mapping = page_mapping(page);
71 unsigned long addr; 71 unsigned long addr;
72 72
73 if (PageHighMem(page))
74 return;
73 if (mapping && !mapping_mapped(mapping)) { 75 if (mapping && !mapping_mapped(mapping)) {
74 SetPageDcacheDirty(page); 76 SetPageDcacheDirty(page);
75 return; 77 return;
@@ -91,16 +93,16 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
91{ 93{
92 struct page *page; 94 struct page *page;
93 unsigned long pfn, addr; 95 unsigned long pfn, addr;
96 int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
94 97
95 pfn = pte_pfn(pte); 98 pfn = pte_pfn(pte);
96 if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && 99 if (unlikely(!pfn_valid(pfn)))
97 Page_dcache_dirty(page)) { 100 return;
98 if (pages_do_alias((unsigned long)page_address(page), 101 page = pfn_to_page(pfn);
99 address & PAGE_MASK)) { 102 if (page_mapping(page) && Page_dcache_dirty(page)) {
100 addr = (unsigned long) page_address(page); 103 addr = (unsigned long) page_address(page);
104 if (exec || pages_do_alias(addr, address & PAGE_MASK))
101 flush_data_cache_page(addr); 105 flush_data_cache_page(addr);
102 }
103
104 ClearPageDcacheDirty(page); 106 ClearPageDcacheDirty(page);
105 } 107 }
106} 108}