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
84struct mmu_gather {
85 struct mm_struct *mm;
86#ifdef CONFIG_HAVE_RCU_TABLE_FREE
87 struct mmu_table_batch *batch;
88#endif
89 unsigned int need_flush : 1,
90 fast_mode : 1;
91
92 unsigned int fullmm;
93
94 struct mmu_gather_batch *active;
95 struct mmu_gather_batch local;
96 struct page *__pages[MMU_GATHER_BUNDLE];
97};
98
99#define HAVE_GENERIC_MMU_GATHER
100
101static inline int tlb_fast_mode(struct mmu_gather *tlb)
102{
103#ifdef CONFIG_SMP
104 return tlb->fast_mode;
105#else
106
107
108
109
110 return 1;
111#endif
112}
113
114void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
115void tlb_flush_mmu(struct mmu_gather *tlb);
116void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end);
117int __tlb_remove_page(struct mmu_gather *tlb, struct page *page);
118
119
120
121
122
123static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
124{
125 if (!__tlb_remove_page(tlb, page))
126 tlb_flush_mmu(tlb);
127}
128
129
130
131
132
133
134
135
136#define tlb_remove_tlb_entry(tlb, ptep, address) \
137 do { \
138 tlb->need_flush = 1; \
139 __tlb_remove_tlb_entry(tlb, ptep, address); \
140 } while (0)
141
142#define pte_free_tlb(tlb, ptep, address) \
143 do { \
144 tlb->need_flush = 1; \
145 __pte_free_tlb(tlb, ptep, address); \
146 } while (0)
147
148#ifndef __ARCH_HAS_4LEVEL_HACK
149#define pud_free_tlb(tlb, pudp, address) \
150 do { \
151 tlb->need_flush = 1; \
152 __pud_free_tlb(tlb, pudp, address); \
153 } while (0)
154#endif
155
156#define pmd_free_tlb(tlb, pmdp, address) \
157 do { \
158 tlb->need_flush = 1; \
159 __pmd_free_tlb(tlb, pmdp, address); \
160 } while (0)
161
162#define tlb_migrate_finish(mm) do {} while (0)
163
164#endif
165