diff options
Diffstat (limited to 'include/asm-sparc64/tlb.h')
-rw-r--r-- | include/asm-sparc64/tlb.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h new file mode 100644 index 000000000000..9baf57db01d2 --- /dev/null +++ b/include/asm-sparc64/tlb.h | |||
@@ -0,0 +1,128 @@ | |||
1 | #ifndef _SPARC64_TLB_H | ||
2 | #define _SPARC64_TLB_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | #include <linux/swap.h> | ||
6 | #include <asm/pgalloc.h> | ||
7 | #include <asm/tlbflush.h> | ||
8 | #include <asm/mmu_context.h> | ||
9 | |||
10 | #define TLB_BATCH_NR 192 | ||
11 | |||
12 | /* | ||
13 | * For UP we don't need to worry about TLB flush | ||
14 | * and page free order so much.. | ||
15 | */ | ||
16 | #ifdef CONFIG_SMP | ||
17 | #define FREE_PTE_NR 506 | ||
18 | #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U) | ||
19 | #else | ||
20 | #define FREE_PTE_NR 1 | ||
21 | #define tlb_fast_mode(bp) 1 | ||
22 | #endif | ||
23 | |||
24 | struct mmu_gather { | ||
25 | struct mm_struct *mm; | ||
26 | unsigned int pages_nr; | ||
27 | unsigned int need_flush; | ||
28 | unsigned int tlb_frozen; | ||
29 | unsigned int tlb_nr; | ||
30 | unsigned long freed; | ||
31 | unsigned long vaddrs[TLB_BATCH_NR]; | ||
32 | struct page *pages[FREE_PTE_NR]; | ||
33 | }; | ||
34 | |||
35 | DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
36 | |||
37 | #ifdef CONFIG_SMP | ||
38 | extern void smp_flush_tlb_pending(struct mm_struct *, | ||
39 | unsigned long, unsigned long *); | ||
40 | #endif | ||
41 | |||
42 | extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *); | ||
43 | extern void flush_tlb_pending(void); | ||
44 | |||
45 | static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) | ||
46 | { | ||
47 | struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); | ||
48 | |||
49 | BUG_ON(mp->tlb_nr); | ||
50 | |||
51 | mp->mm = mm; | ||
52 | mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U; | ||
53 | mp->tlb_frozen = full_mm_flush; | ||
54 | mp->freed = 0; | ||
55 | |||
56 | return mp; | ||
57 | } | ||
58 | |||
59 | |||
60 | static inline void tlb_flush_mmu(struct mmu_gather *mp) | ||
61 | { | ||
62 | if (mp->need_flush) { | ||
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 | } | ||
69 | |||
70 | } | ||
71 | |||
72 | #ifdef CONFIG_SMP | ||
73 | extern void smp_flush_tlb_mm(struct mm_struct *mm); | ||
74 | #define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm) | ||
75 | #else | ||
76 | #define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT) | ||
77 | #endif | ||
78 | |||
79 | static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end) | ||
80 | { | ||
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); | ||
90 | |||
91 | if (mp->tlb_frozen) { | ||
92 | if (CTX_VALID(mm->context)) | ||
93 | do_flush_tlb_mm(mm); | ||
94 | mp->tlb_frozen = 0; | ||
95 | } else | ||
96 | flush_tlb_pending(); | ||
97 | |||
98 | /* keep the page table cache within bounds */ | ||
99 | check_pgt_cache(); | ||
100 | } | ||
101 | |||
102 | static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp) | ||
103 | { | ||
104 | return mp->tlb_frozen; | ||
105 | } | ||
106 | |||
107 | static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) | ||
108 | { | ||
109 | mp->need_flush = 1; | ||
110 | if (tlb_fast_mode(mp)) { | ||
111 | free_page_and_swap_cache(page); | ||
112 | return; | ||
113 | } | ||
114 | mp->pages[mp->pages_nr++] = page; | ||
115 | if (mp->pages_nr >= FREE_PTE_NR) | ||
116 | tlb_flush_mmu(mp); | ||
117 | } | ||
118 | |||
119 | #define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0) | ||
120 | #define pte_free_tlb(mp,ptepage) pte_free(ptepage) | ||
121 | #define pmd_free_tlb(mp,pmdp) pmd_free(pmdp) | ||
122 | #define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp) | ||
123 | |||
124 | #define tlb_migrate_finish(mm) do { } while (0) | ||
125 | #define tlb_start_vma(tlb, vma) do { } while (0) | ||
126 | #define tlb_end_vma(tlb, vma) do { } while (0) | ||
127 | |||
128 | #endif /* _SPARC64_TLB_H */ | ||