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
101
102 fullmm : 1,
103
104
105 need_flush_all : 1;
106
107 struct mmu_gather_batch *active;
108 struct mmu_gather_batch local;
109 struct page *__pages[MMU_GATHER_BUNDLE];
110 unsigned int batch_count;
111};
112
113#define HAVE_GENERIC_MMU_GATHER
114
115void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end);
116void tlb_flush_mmu(struct mmu_gather *tlb);
117void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
118 unsigned long end);
119int __tlb_remove_page(struct mmu_gather *tlb, struct page *page);
120
121
122
123
124
125static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
126{
127 if (!__tlb_remove_page(tlb, page))
128 tlb_flush_mmu(tlb);
129}
130
131
132
133
134
135
136
137
138#define tlb_remove_tlb_entry(tlb, ptep, address) \
139 do { \
140 tlb->need_flush = 1; \
141 __tlb_remove_tlb_entry(tlb, ptep, address); \
142 } while (0)
143
144
145
146
147
148#ifndef __tlb_remove_pmd_tlb_entry
149#define __tlb_remove_pmd_tlb_entry(tlb, pmdp, address) do {} while (0)
150#endif
151
152#define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \
153 do { \
154 tlb->need_flush = 1; \
155 __tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \
156 } while (0)
157
158#define pte_free_tlb(tlb, ptep, address) \
159 do { \
160 tlb->need_flush = 1; \
161 __pte_free_tlb(tlb, ptep, address); \
162 } while (0)
163
164#ifndef __ARCH_HAS_4LEVEL_HACK
165#define pud_free_tlb(tlb, pudp, address) \
166 do { \
167 tlb->need_flush = 1; \
168 __pud_free_tlb(tlb, pudp, address); \
169 } while (0)
170#endif
171
172#define pmd_free_tlb(tlb, pmdp, address) \
173 do { \
174 tlb->need_flush = 1; \
175 __pmd_free_tlb(tlb, pmdp, address); \
176 } while (0)
177
178#define tlb_migrate_finish(mm) do {} while (0)
179
180#endif
181