aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmu_notifier.h
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /include/linux/mmu_notifier.h
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'include/linux/mmu_notifier.h')
-rw-r--r--include/linux/mmu_notifier.h70
1 files changed, 68 insertions, 2 deletions
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index 4e02ee2b071e..1d1b1e13f79f 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -62,6 +62,16 @@ struct mmu_notifier_ops {
62 unsigned long address); 62 unsigned long address);
63 63
64 /* 64 /*
65 * test_young is called to check the young/accessed bitflag in
66 * the secondary pte. This is used to know if the page is
67 * frequently used without actually clearing the flag or tearing
68 * down the secondary mapping on the page.
69 */
70 int (*test_young)(struct mmu_notifier *mn,
71 struct mm_struct *mm,
72 unsigned long address);
73
74 /*
65 * change_pte is called in cases that pte mapping to page is changed: 75 * change_pte is called in cases that pte mapping to page is changed:
66 * for example, when ksm remaps pte to point to a new shared page. 76 * for example, when ksm remaps pte to point to a new shared page.
67 */ 77 */
@@ -140,7 +150,7 @@ struct mmu_notifier_ops {
140 * Therefore notifier chains can only be traversed when either 150 * Therefore notifier chains can only be traversed when either
141 * 151 *
142 * 1. mmap_sem is held. 152 * 1. mmap_sem is held.
143 * 2. One of the reverse map locks is held (i_mmap_lock or anon_vma->lock). 153 * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->mutex).
144 * 3. No other concurrent thread can access the list (release) 154 * 3. No other concurrent thread can access the list (release)
145 */ 155 */
146struct mmu_notifier { 156struct mmu_notifier {
@@ -163,6 +173,8 @@ extern void __mmu_notifier_mm_destroy(struct mm_struct *mm);
163extern void __mmu_notifier_release(struct mm_struct *mm); 173extern void __mmu_notifier_release(struct mm_struct *mm);
164extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm, 174extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
165 unsigned long address); 175 unsigned long address);
176extern int __mmu_notifier_test_young(struct mm_struct *mm,
177 unsigned long address);
166extern void __mmu_notifier_change_pte(struct mm_struct *mm, 178extern void __mmu_notifier_change_pte(struct mm_struct *mm,
167 unsigned long address, pte_t pte); 179 unsigned long address, pte_t pte);
168extern void __mmu_notifier_invalidate_page(struct mm_struct *mm, 180extern void __mmu_notifier_invalidate_page(struct mm_struct *mm,
@@ -186,6 +198,14 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
186 return 0; 198 return 0;
187} 199}
188 200
201static inline int mmu_notifier_test_young(struct mm_struct *mm,
202 unsigned long address)
203{
204 if (mm_has_notifiers(mm))
205 return __mmu_notifier_test_young(mm, address);
206 return 0;
207}
208
189static inline void mmu_notifier_change_pte(struct mm_struct *mm, 209static inline void mmu_notifier_change_pte(struct mm_struct *mm,
190 unsigned long address, pte_t pte) 210 unsigned long address, pte_t pte)
191{ 211{
@@ -227,7 +247,7 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
227 247
228/* 248/*
229 * These two macros will sometime replace ptep_clear_flush. 249 * These two macros will sometime replace ptep_clear_flush.
230 * ptep_clear_flush is impleemnted as macro itself, so this also is 250 * ptep_clear_flush is implemented as macro itself, so this also is
231 * implemented as a macro until ptep_clear_flush will converted to an 251 * implemented as a macro until ptep_clear_flush will converted to an
232 * inline function, to diminish the risk of compilation failure. The 252 * inline function, to diminish the risk of compilation failure. The
233 * invalidate_page method over time can be moved outside the PT lock 253 * invalidate_page method over time can be moved outside the PT lock
@@ -243,6 +263,32 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
243 __pte; \ 263 __pte; \
244}) 264})
245 265
266#define pmdp_clear_flush_notify(__vma, __address, __pmdp) \
267({ \
268 pmd_t __pmd; \
269 struct vm_area_struct *___vma = __vma; \
270 unsigned long ___address = __address; \
271 VM_BUG_ON(__address & ~HPAGE_PMD_MASK); \
272 mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address, \
273 (__address)+HPAGE_PMD_SIZE);\
274 __pmd = pmdp_clear_flush(___vma, ___address, __pmdp); \
275 mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address, \
276 (__address)+HPAGE_PMD_SIZE); \
277 __pmd; \
278})
279
280#define pmdp_splitting_flush_notify(__vma, __address, __pmdp) \
281({ \
282 struct vm_area_struct *___vma = __vma; \
283 unsigned long ___address = __address; \
284 VM_BUG_ON(__address & ~HPAGE_PMD_MASK); \
285 mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address, \
286 (__address)+HPAGE_PMD_SIZE);\
287 pmdp_splitting_flush(___vma, ___address, __pmdp); \
288 mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address, \
289 (__address)+HPAGE_PMD_SIZE); \
290})
291
246#define ptep_clear_flush_young_notify(__vma, __address, __ptep) \ 292#define ptep_clear_flush_young_notify(__vma, __address, __ptep) \
247({ \ 293({ \
248 int __young; \ 294 int __young; \
@@ -254,6 +300,17 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
254 __young; \ 300 __young; \
255}) 301})
256 302
303#define pmdp_clear_flush_young_notify(__vma, __address, __pmdp) \
304({ \
305 int __young; \
306 struct vm_area_struct *___vma = __vma; \
307 unsigned long ___address = __address; \
308 __young = pmdp_clear_flush_young(___vma, ___address, __pmdp); \
309 __young |= mmu_notifier_clear_flush_young(___vma->vm_mm, \
310 ___address); \
311 __young; \
312})
313
257#define set_pte_at_notify(__mm, __address, __ptep, __pte) \ 314#define set_pte_at_notify(__mm, __address, __ptep, __pte) \
258({ \ 315({ \
259 struct mm_struct *___mm = __mm; \ 316 struct mm_struct *___mm = __mm; \
@@ -276,6 +333,12 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
276 return 0; 333 return 0;
277} 334}
278 335
336static inline int mmu_notifier_test_young(struct mm_struct *mm,
337 unsigned long address)
338{
339 return 0;
340}
341
279static inline void mmu_notifier_change_pte(struct mm_struct *mm, 342static inline void mmu_notifier_change_pte(struct mm_struct *mm,
280 unsigned long address, pte_t pte) 343 unsigned long address, pte_t pte)
281{ 344{
@@ -305,7 +368,10 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
305} 368}
306 369
307#define ptep_clear_flush_young_notify ptep_clear_flush_young 370#define ptep_clear_flush_young_notify ptep_clear_flush_young
371#define pmdp_clear_flush_young_notify pmdp_clear_flush_young
308#define ptep_clear_flush_notify ptep_clear_flush 372#define ptep_clear_flush_notify ptep_clear_flush
373#define pmdp_clear_flush_notify pmdp_clear_flush
374#define pmdp_splitting_flush_notify pmdp_splitting_flush
309#define set_pte_at_notify set_pte_at 375#define set_pte_at_notify set_pte_at
310 376
311#endif /* CONFIG_MMU_NOTIFIER */ 377#endif /* CONFIG_MMU_NOTIFIER */