diff options
Diffstat (limited to 'include/linux/mmu_notifier.h')
| -rw-r--r-- | include/linux/mmu_notifier.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 43dcfbdc39de..cc2e7dfea9d7 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 | */ |
| @@ -163,6 +173,8 @@ extern void __mmu_notifier_mm_destroy(struct mm_struct *mm); | |||
| 163 | extern void __mmu_notifier_release(struct mm_struct *mm); | 173 | extern void __mmu_notifier_release(struct mm_struct *mm); |
| 164 | extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm, | 174 | extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm, |
| 165 | unsigned long address); | 175 | unsigned long address); |
| 176 | extern int __mmu_notifier_test_young(struct mm_struct *mm, | ||
| 177 | unsigned long address); | ||
| 166 | extern void __mmu_notifier_change_pte(struct mm_struct *mm, | 178 | extern void __mmu_notifier_change_pte(struct mm_struct *mm, |
| 167 | unsigned long address, pte_t pte); | 179 | unsigned long address, pte_t pte); |
| 168 | extern void __mmu_notifier_invalidate_page(struct mm_struct *mm, | 180 | extern 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 | ||
| 201 | static 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 | |||
| 189 | static inline void mmu_notifier_change_pte(struct mm_struct *mm, | 209 | static 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 | { |
| @@ -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 | ||
| 336 | static inline int mmu_notifier_test_young(struct mm_struct *mm, | ||
| 337 | unsigned long address) | ||
| 338 | { | ||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 279 | static inline void mmu_notifier_change_pte(struct mm_struct *mm, | 342 | static 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 */ |
