diff options
Diffstat (limited to 'mm/mmu_notifier.c')
-rw-r--r-- | mm/mmu_notifier.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 5119ff846769..9c884abc7850 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c | |||
@@ -35,13 +35,6 @@ void mmu_notifier_call_srcu(struct rcu_head *rcu, | |||
35 | } | 35 | } |
36 | EXPORT_SYMBOL_GPL(mmu_notifier_call_srcu); | 36 | EXPORT_SYMBOL_GPL(mmu_notifier_call_srcu); |
37 | 37 | ||
38 | void mmu_notifier_synchronize(void) | ||
39 | { | ||
40 | /* Wait for any running method to finish. */ | ||
41 | srcu_barrier(&srcu); | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(mmu_notifier_synchronize); | ||
44 | |||
45 | /* | 38 | /* |
46 | * This function can't run concurrently against mmu_notifier_register | 39 | * This function can't run concurrently against mmu_notifier_register |
47 | * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap | 40 | * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap |
@@ -174,22 +167,20 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, | |||
174 | srcu_read_unlock(&srcu, id); | 167 | srcu_read_unlock(&srcu, id); |
175 | } | 168 | } |
176 | 169 | ||
177 | int __mmu_notifier_invalidate_range_start(struct mm_struct *mm, | 170 | int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range) |
178 | unsigned long start, unsigned long end, | ||
179 | bool blockable) | ||
180 | { | 171 | { |
181 | struct mmu_notifier *mn; | 172 | struct mmu_notifier *mn; |
182 | int ret = 0; | 173 | int ret = 0; |
183 | int id; | 174 | int id; |
184 | 175 | ||
185 | id = srcu_read_lock(&srcu); | 176 | id = srcu_read_lock(&srcu); |
186 | hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { | 177 | hlist_for_each_entry_rcu(mn, &range->mm->mmu_notifier_mm->list, hlist) { |
187 | if (mn->ops->invalidate_range_start) { | 178 | if (mn->ops->invalidate_range_start) { |
188 | int _ret = mn->ops->invalidate_range_start(mn, mm, start, end, blockable); | 179 | int _ret = mn->ops->invalidate_range_start(mn, range); |
189 | if (_ret) { | 180 | if (_ret) { |
190 | pr_info("%pS callback failed with %d in %sblockable context.\n", | 181 | pr_info("%pS callback failed with %d in %sblockable context.\n", |
191 | mn->ops->invalidate_range_start, _ret, | 182 | mn->ops->invalidate_range_start, _ret, |
192 | !blockable ? "non-" : ""); | 183 | !range->blockable ? "non-" : ""); |
193 | ret = _ret; | 184 | ret = _ret; |
194 | } | 185 | } |
195 | } | 186 | } |
@@ -200,16 +191,14 @@ int __mmu_notifier_invalidate_range_start(struct mm_struct *mm, | |||
200 | } | 191 | } |
201 | EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_start); | 192 | EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_start); |
202 | 193 | ||
203 | void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | 194 | void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range, |
204 | unsigned long start, | ||
205 | unsigned long end, | ||
206 | bool only_end) | 195 | bool only_end) |
207 | { | 196 | { |
208 | struct mmu_notifier *mn; | 197 | struct mmu_notifier *mn; |
209 | int id; | 198 | int id; |
210 | 199 | ||
211 | id = srcu_read_lock(&srcu); | 200 | id = srcu_read_lock(&srcu); |
212 | hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { | 201 | hlist_for_each_entry_rcu(mn, &range->mm->mmu_notifier_mm->list, hlist) { |
213 | /* | 202 | /* |
214 | * Call invalidate_range here too to avoid the need for the | 203 | * Call invalidate_range here too to avoid the need for the |
215 | * subsystem of having to register an invalidate_range_end | 204 | * subsystem of having to register an invalidate_range_end |
@@ -224,9 +213,11 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | |||
224 | * already happen under page table lock. | 213 | * already happen under page table lock. |
225 | */ | 214 | */ |
226 | if (!only_end && mn->ops->invalidate_range) | 215 | if (!only_end && mn->ops->invalidate_range) |
227 | mn->ops->invalidate_range(mn, mm, start, end); | 216 | mn->ops->invalidate_range(mn, range->mm, |
217 | range->start, | ||
218 | range->end); | ||
228 | if (mn->ops->invalidate_range_end) | 219 | if (mn->ops->invalidate_range_end) |
229 | mn->ops->invalidate_range_end(mn, mm, start, end); | 220 | mn->ops->invalidate_range_end(mn, range); |
230 | } | 221 | } |
231 | srcu_read_unlock(&srcu, id); | 222 | srcu_read_unlock(&srcu, id); |
232 | } | 223 | } |