1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef _ASM_GENERIC__TLB_H
16#define _ASM_GENERIC__TLB_H
17
18#include <linux/swap.h>
19#include <asm/pgalloc.h>
20#include <asm/tlbflush.h>
21
22#ifdef CONFIG_HAVE_RCU_TABLE_FREE
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51struct mmu_table_batch {
52 struct rcu_head rcu;
53 unsigned int nr;
54 void *tables[0];
55};
56
57#define MAX_TABLE_BATCH \
58 ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
59
60extern void tlb_table_flush(struct mmu_gather *tlb);
61extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
62
63#endif
64
65
66
67
68
69#define MMU_GATHER_BUNDLE 8
70
71struct mmu_gather_batch {
72 struct mmu_gather_batch *next;
73 unsigned int nr;
74 unsigned int max;
75 struct page *pages[0];
76};
77
78#define MAX_GATHER_BATCH \
79 ((PAGE_SIZE - sizeof(struct mmu_gather_batch)) / sizeof(void *))
80
81
82
83
84
85
86
87#define MAX_GATHER_BATCH_COUNT (10000UL/MAX_GATHER_BATCH)
88
89
90
91
92struct mmu_gather {
93 struct mm_struct *mm;
94#ifdef CONFIG_HAVE_RCU_TABLE_FREE
95 struct mmu_table_batch *batch;
96#endif
97 unsigned long start;
98 unsigned long end;
99 unsigned int need_flush : 1,
100 fast_mode : 1;
101
102 unsigned int fullmm;
103
104 struct mmu_gather_batch *active;
105 struct mmu_gather_batch local;
106 struct page *__pages[MMU_GATHER_BUNDLE];
107 unsigned int batch_count;
108};
109
110#define HAVE_GENERIC_MMU_GATHER
111
112static inline int tlb_fast_mode(struct mmu_gather *tlb)
113{
114#ifdef CONFIG_SMP
115 return tlb->fast_mode;
116#else
117
118
119
120
121 return 1;
122#endif
123}
124
125void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
126void tlb_flush_mmu(struct mmu_gather *tlb);
127void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
128 unsigned long end);
129int __tlb_remove_page(struct mmu_gather *tlb, struct page *page);
130
131
132
133
134
135static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
136{
137 if (!__tlb_remove_page(tlb, page))
138 tlb_flush_mmu(tlb);
139}
140
141
142
143
144
145
146
147
148#define tlb_remove_tlb_entry(tlb, ptep, address) \
149 do { \
150 tlb->need_flush = 1; \
151 __tlb_remove_tlb_entry(tlb, ptep, address); \
152 } while (0)
153
154
155
156
157
158#ifndef __tlb_remove_pmd_tlb_entry
159#define __tlb_remove_pmd_tlb_entry(tlb, pmdp, address) do {} while (0)
160#endif
161
162#define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \
163 do { \
164 tlb->need_flush = 1; \
165 __tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \
166 } while (0)
167
168#define pte_free_tlb(tlb, ptep, address) \
169 do { \
170 tlb->need_flush = 1; \
171 __pte_free_tlb(tlb, ptep, address); \
172 } while (0)
173
174#ifndef __ARCH_HAS_4LEVEL_HACK
175#define pud_free_tlb(tlb, pudp, address) \
176 do { \
177 tlb->need_flush = 1; \
178 __pud_free_tlb(tlb, pudp, address); \
179 } while (0)
180#endif
181
182#define pmd_free_tlb(tlb, pmdp, address) \
183 do { \
184 tlb->need_flush = 1; \
185 __pmd_free_tlb(tlb, pmdp, address); \
186 } while (0)
187
188#define tlb_migrate_finish(mm) do {} while (0)
189
190#endif
191