aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64/tlb.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-sparc64/tlb.h')
-rw-r--r--include/asm-sparc64/tlb.h37
1 files changed, 10 insertions, 27 deletions
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
index 9baf57db01d2..61c01882b562 100644
--- a/include/asm-sparc64/tlb.h
+++ b/include/asm-sparc64/tlb.h
@@ -25,9 +25,8 @@ struct mmu_gather {
25 struct mm_struct *mm; 25 struct mm_struct *mm;
26 unsigned int pages_nr; 26 unsigned int pages_nr;
27 unsigned int need_flush; 27 unsigned int need_flush;
28 unsigned int tlb_frozen; 28 unsigned int fullmm;
29 unsigned int tlb_nr; 29 unsigned int tlb_nr;
30 unsigned long freed;
31 unsigned long vaddrs[TLB_BATCH_NR]; 30 unsigned long vaddrs[TLB_BATCH_NR];
32 struct page *pages[FREE_PTE_NR]; 31 struct page *pages[FREE_PTE_NR];
33}; 32};
@@ -44,14 +43,13 @@ extern void flush_tlb_pending(void);
44 43
45static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) 44static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
46{ 45{
47 struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); 46 struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
48 47
49 BUG_ON(mp->tlb_nr); 48 BUG_ON(mp->tlb_nr);
50 49
51 mp->mm = mm; 50 mp->mm = mm;
52 mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U; 51 mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
53 mp->tlb_frozen = full_mm_flush; 52 mp->fullmm = full_mm_flush;
54 mp->freed = 0;
55 53
56 return mp; 54 return mp;
57} 55}
@@ -60,11 +58,9 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned i
60static inline void tlb_flush_mmu(struct mmu_gather *mp) 58static inline void tlb_flush_mmu(struct mmu_gather *mp)
61{ 59{
62 if (mp->need_flush) { 60 if (mp->need_flush) {
61 free_pages_and_swap_cache(mp->pages, mp->pages_nr);
62 mp->pages_nr = 0;
63 mp->need_flush = 0; 63 mp->need_flush = 0;
64 if (!tlb_fast_mode(mp)) {
65 free_pages_and_swap_cache(mp->pages, mp->pages_nr);
66 mp->pages_nr = 0;
67 }
68 } 64 }
69 65
70} 66}
@@ -78,39 +74,26 @@ extern void smp_flush_tlb_mm(struct mm_struct *mm);
78 74
79static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end) 75static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
80{ 76{
81 unsigned long freed = mp->freed;
82 struct mm_struct *mm = mp->mm;
83 unsigned long rss = get_mm_counter(mm, rss);
84
85 if (rss < freed)
86 freed = rss;
87 add_mm_counter(mm, rss, -freed);
88
89 tlb_flush_mmu(mp); 77 tlb_flush_mmu(mp);
90 78
91 if (mp->tlb_frozen) { 79 if (mp->fullmm)
92 if (CTX_VALID(mm->context)) 80 mp->fullmm = 0;
93 do_flush_tlb_mm(mm); 81 else
94 mp->tlb_frozen = 0;
95 } else
96 flush_tlb_pending(); 82 flush_tlb_pending();
97 83
98 /* keep the page table cache within bounds */ 84 /* keep the page table cache within bounds */
99 check_pgt_cache(); 85 check_pgt_cache();
100}
101 86
102static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp) 87 put_cpu_var(mmu_gathers);
103{
104 return mp->tlb_frozen;
105} 88}
106 89
107static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) 90static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
108{ 91{
109 mp->need_flush = 1;
110 if (tlb_fast_mode(mp)) { 92 if (tlb_fast_mode(mp)) {
111 free_page_and_swap_cache(page); 93 free_page_and_swap_cache(page);
112 return; 94 return;
113 } 95 }
96 mp->need_flush = 1;
114 mp->pages[mp->pages_nr++] = page; 97 mp->pages[mp->pages_nr++] = page;
115 if (mp->pages_nr >= FREE_PTE_NR) 98 if (mp->pages_nr >= FREE_PTE_NR)
116 tlb_flush_mmu(mp); 99 tlb_flush_mmu(mp);