diff options
Diffstat (limited to 'include/asm-sparc64/tlb.h')
-rw-r--r-- | include/asm-sparc64/tlb.h | 37 |
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 | ||
45 | static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) | 44 | static 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 | |||
60 | static inline void tlb_flush_mmu(struct mmu_gather *mp) | 58 | static 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 | ||
79 | static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end) | 75 | static 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 | ||
102 | static 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 | ||
107 | static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) | 90 | static 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); |