diff options
Diffstat (limited to 'include/linux/mmu_notifier.h')
-rw-r--r-- | include/linux/mmu_notifier.h | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index b25dc9db19fc..2d07a1ed5a31 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #ifndef _LINUX_MMU_NOTIFIER_H | 2 | #ifndef _LINUX_MMU_NOTIFIER_H |
3 | #define _LINUX_MMU_NOTIFIER_H | 3 | #define _LINUX_MMU_NOTIFIER_H |
4 | 4 | ||
5 | #include <linux/types.h> | ||
5 | #include <linux/list.h> | 6 | #include <linux/list.h> |
6 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
7 | #include <linux/mm_types.h> | 8 | #include <linux/mm_types.h> |
@@ -10,6 +11,9 @@ | |||
10 | struct mmu_notifier; | 11 | struct mmu_notifier; |
11 | struct mmu_notifier_ops; | 12 | struct mmu_notifier_ops; |
12 | 13 | ||
14 | /* mmu_notifier_ops flags */ | ||
15 | #define MMU_INVALIDATE_DOES_NOT_BLOCK (0x01) | ||
16 | |||
13 | #ifdef CONFIG_MMU_NOTIFIER | 17 | #ifdef CONFIG_MMU_NOTIFIER |
14 | 18 | ||
15 | /* | 19 | /* |
@@ -27,6 +31,15 @@ struct mmu_notifier_mm { | |||
27 | 31 | ||
28 | struct mmu_notifier_ops { | 32 | struct mmu_notifier_ops { |
29 | /* | 33 | /* |
34 | * Flags to specify behavior of callbacks for this MMU notifier. | ||
35 | * Used to determine which context an operation may be called. | ||
36 | * | ||
37 | * MMU_INVALIDATE_DOES_NOT_BLOCK: invalidate_range_* callbacks do not | ||
38 | * block | ||
39 | */ | ||
40 | int flags; | ||
41 | |||
42 | /* | ||
30 | * Called either by mmu_notifier_unregister or when the mm is | 43 | * Called either by mmu_notifier_unregister or when the mm is |
31 | * being destroyed by exit_mmap, always before all pages are | 44 | * being destroyed by exit_mmap, always before all pages are |
32 | * freed. This can run concurrently with other mmu notifier | 45 | * freed. This can run concurrently with other mmu notifier |
@@ -137,6 +150,10 @@ struct mmu_notifier_ops { | |||
137 | * page. Pages will no longer be referenced by the linux | 150 | * page. Pages will no longer be referenced by the linux |
138 | * address space but may still be referenced by sptes until | 151 | * address space but may still be referenced by sptes until |
139 | * the last refcount is dropped. | 152 | * the last refcount is dropped. |
153 | * | ||
154 | * If both of these callbacks cannot block, and invalidate_range | ||
155 | * cannot block, mmu_notifier_ops.flags should have | ||
156 | * MMU_INVALIDATE_DOES_NOT_BLOCK set. | ||
140 | */ | 157 | */ |
141 | void (*invalidate_range_start)(struct mmu_notifier *mn, | 158 | void (*invalidate_range_start)(struct mmu_notifier *mn, |
142 | struct mm_struct *mm, | 159 | struct mm_struct *mm, |
@@ -159,12 +176,13 @@ struct mmu_notifier_ops { | |||
159 | * external TLB range needs to be flushed. For more in depth | 176 | * external TLB range needs to be flushed. For more in depth |
160 | * discussion on this see Documentation/vm/mmu_notifier.txt | 177 | * discussion on this see Documentation/vm/mmu_notifier.txt |
161 | * | 178 | * |
162 | * The invalidate_range() function is called under the ptl | ||
163 | * spin-lock and not allowed to sleep. | ||
164 | * | ||
165 | * Note that this function might be called with just a sub-range | 179 | * Note that this function might be called with just a sub-range |
166 | * of what was passed to invalidate_range_start()/end(), if | 180 | * of what was passed to invalidate_range_start()/end(), if |
167 | * called between those functions. | 181 | * called between those functions. |
182 | * | ||
183 | * If this callback cannot block, and invalidate_range_{start,end} | ||
184 | * cannot block, mmu_notifier_ops.flags should have | ||
185 | * MMU_INVALIDATE_DOES_NOT_BLOCK set. | ||
168 | */ | 186 | */ |
169 | void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, | 187 | void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, |
170 | unsigned long start, unsigned long end); | 188 | unsigned long start, unsigned long end); |
@@ -218,6 +236,7 @@ extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | |||
218 | bool only_end); | 236 | bool only_end); |
219 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, | 237 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, |
220 | unsigned long start, unsigned long end); | 238 | unsigned long start, unsigned long end); |
239 | extern bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm); | ||
221 | 240 | ||
222 | static inline void mmu_notifier_release(struct mm_struct *mm) | 241 | static inline void mmu_notifier_release(struct mm_struct *mm) |
223 | { | 242 | { |
@@ -457,6 +476,11 @@ static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, | |||
457 | { | 476 | { |
458 | } | 477 | } |
459 | 478 | ||
479 | static inline bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm) | ||
480 | { | ||
481 | return false; | ||
482 | } | ||
483 | |||
460 | static inline void mmu_notifier_mm_init(struct mm_struct *mm) | 484 | static inline void mmu_notifier_mm_init(struct mm_struct *mm) |
461 | { | 485 | { |
462 | } | 486 | } |