aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJérôme Glisse <jglisse@redhat.com>2018-12-28 03:38:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-28 15:11:50 -0500
commit5d6527a784f7a6d247961e046e830de8d71b47d1 (patch)
tree9326a7abb7aab8983770840a4d52e07becb76c6d /drivers
parentb15c87263a69272423771118c653e9a1d0672caa (diff)
mm/mmu_notifier: use structure for invalidate_range_start/end callback
Patch series "mmu notifier contextual informations", v2. This patchset adds contextual information, why an invalidation is happening, to mmu notifier callback. This is necessary for user of mmu notifier that wish to maintains their own data structure without having to add new fields to struct vm_area_struct (vma). For instance device can have they own page table that mirror the process address space. When a vma is unmap (munmap() syscall) the device driver can free the device page table for the range. Today we do not have any information on why a mmu notifier call back is happening and thus device driver have to assume that it is always an munmap(). This is inefficient at it means that it needs to re-allocate device page table on next page fault and rebuild the whole device driver data structure for the range. Other use case beside munmap() also exist, for instance it is pointless for device driver to invalidate the device page table when the invalidation is for the soft dirtyness tracking. Or device driver can optimize away mprotect() that change the page table permission access for the range. This patchset enables all this optimizations for device drivers. I do not include any of those in this series but another patchset I am posting will leverage this. The patchset is pretty simple from a code point of view. The first two patches consolidate all mmu notifier arguments into a struct so that it is easier to add/change arguments. The last patch adds the contextual information (munmap, protection, soft dirty, clear, ...). This patch (of 3): To avoid having to change many callback definition everytime we want to add a parameter use a structure to group all parameters for the mmu_notifier invalidate_range_start/end callback. No functional changes with this patch. [akpm@linux-foundation.org: fix drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c kerneldoc] Link: http://lkml.kernel.org/r/20181205053628.3210-2-jglisse@redhat.com Signed-off-by: Jérôme Glisse <jglisse@redhat.com> Acked-by: Jan Kara <jack@suse.cz> Acked-by: Jason Gunthorpe <jgg@mellanox.com> [infiniband] Cc: Matthew Wilcox <mawilcox@microsoft.com> Cc: Ross Zwisler <zwisler@kernel.org> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Radim Krcmar <rkrcmar@redhat.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Christian Koenig <christian.koenig@amd.com> Cc: Felix Kuehling <felix.kuehling@amd.com> Cc: Ralph Campbell <rcampbell@nvidia.com> Cc: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c47
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_mn.c16
-rw-r--r--drivers/infiniband/core/umem_odp.c20
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.c13
-rw-r--r--drivers/misc/mic/scif/scif_dma.c11
-rw-r--r--drivers/misc/sgi-gru/grutlbpurge.c14
-rw-r--r--drivers/xen/gntdev.c12
8 files changed, 61 insertions, 86 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index e55508b39496..3e6823fdd939 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -238,44 +238,40 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
238 * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change 238 * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change
239 * 239 *
240 * @mn: our notifier 240 * @mn: our notifier
241 * @mm: the mm this callback is about 241 * @range: mmu notifier context
242 * @start: start of updated range
243 * @end: end of updated range
244 * 242 *
245 * Block for operations on BOs to finish and mark pages as accessed and 243 * Block for operations on BOs to finish and mark pages as accessed and
246 * potentially dirty. 244 * potentially dirty.
247 */ 245 */
248static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, 246static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
249 struct mm_struct *mm, 247 const struct mmu_notifier_range *range)
250 unsigned long start,
251 unsigned long end,
252 bool blockable)
253{ 248{
254 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 249 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
255 struct interval_tree_node *it; 250 struct interval_tree_node *it;
251 unsigned long end;
256 252
257 /* notification is exclusive, but interval is inclusive */ 253 /* notification is exclusive, but interval is inclusive */
258 end -= 1; 254 end = range->end - 1;
259 255
260 /* TODO we should be able to split locking for interval tree and 256 /* TODO we should be able to split locking for interval tree and
261 * amdgpu_mn_invalidate_node 257 * amdgpu_mn_invalidate_node
262 */ 258 */
263 if (amdgpu_mn_read_lock(amn, blockable)) 259 if (amdgpu_mn_read_lock(amn, range->blockable))
264 return -EAGAIN; 260 return -EAGAIN;
265 261
266 it = interval_tree_iter_first(&amn->objects, start, end); 262 it = interval_tree_iter_first(&amn->objects, range->start, end);
267 while (it) { 263 while (it) {
268 struct amdgpu_mn_node *node; 264 struct amdgpu_mn_node *node;
269 265
270 if (!blockable) { 266 if (!range->blockable) {
271 amdgpu_mn_read_unlock(amn); 267 amdgpu_mn_read_unlock(amn);
272 return -EAGAIN; 268 return -EAGAIN;
273 } 269 }
274 270
275 node = container_of(it, struct amdgpu_mn_node, it); 271 node = container_of(it, struct amdgpu_mn_node, it);
276 it = interval_tree_iter_next(it, start, end); 272 it = interval_tree_iter_next(it, range->start, end);
277 273
278 amdgpu_mn_invalidate_node(node, start, end); 274 amdgpu_mn_invalidate_node(node, range->start, end);
279 } 275 }
280 276
281 return 0; 277 return 0;
@@ -294,39 +290,38 @@ static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
294 * are restorted in amdgpu_mn_invalidate_range_end_hsa. 290 * are restorted in amdgpu_mn_invalidate_range_end_hsa.
295 */ 291 */
296static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn, 292static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
297 struct mm_struct *mm, 293 const struct mmu_notifier_range *range)
298 unsigned long start,
299 unsigned long end,
300 bool blockable)
301{ 294{
302 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 295 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
303 struct interval_tree_node *it; 296 struct interval_tree_node *it;
297 unsigned long end;
304 298
305 /* notification is exclusive, but interval is inclusive */ 299 /* notification is exclusive, but interval is inclusive */
306 end -= 1; 300 end = range->end - 1;
307 301
308 if (amdgpu_mn_read_lock(amn, blockable)) 302 if (amdgpu_mn_read_lock(amn, range->blockable))
309 return -EAGAIN; 303 return -EAGAIN;
310 304
311 it = interval_tree_iter_first(&amn->objects, start, end); 305 it = interval_tree_iter_first(&amn->objects, range->start, end);
312 while (it) { 306 while (it) {
313 struct amdgpu_mn_node *node; 307 struct amdgpu_mn_node *node;
314 struct amdgpu_bo *bo; 308 struct amdgpu_bo *bo;
315 309
316 if (!blockable) { 310 if (!range->blockable) {
317 amdgpu_mn_read_unlock(amn); 311 amdgpu_mn_read_unlock(amn);
318 return -EAGAIN; 312 return -EAGAIN;
319 } 313 }
320 314
321 node = container_of(it, struct amdgpu_mn_node, it); 315 node = container_of(it, struct amdgpu_mn_node, it);
322 it = interval_tree_iter_next(it, start, end); 316 it = interval_tree_iter_next(it, range->start, end);
323 317
324 list_for_each_entry(bo, &node->bos, mn_list) { 318 list_for_each_entry(bo, &node->bos, mn_list) {
325 struct kgd_mem *mem = bo->kfd_bo; 319 struct kgd_mem *mem = bo->kfd_bo;
326 320
327 if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, 321 if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm,
328 start, end)) 322 range->start,
329 amdgpu_amdkfd_evict_userptr(mem, mm); 323 end))
324 amdgpu_amdkfd_evict_userptr(mem, range->mm);
330 } 325 }
331 } 326 }
332 327
@@ -344,9 +339,7 @@ static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
344 * Release the lock again to allow new command submissions. 339 * Release the lock again to allow new command submissions.
345 */ 340 */
346static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn, 341static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn,
347 struct mm_struct *mm, 342 const struct mmu_notifier_range *range)
348 unsigned long start,
349 unsigned long end)
350{ 343{
351 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 344 struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
352 345
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 2c9b284036d1..3df77020aada 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -113,27 +113,25 @@ static void del_object(struct i915_mmu_object *mo)
113} 113}
114 114
115static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, 115static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
116 struct mm_struct *mm, 116 const struct mmu_notifier_range *range)
117 unsigned long start,
118 unsigned long end,
119 bool blockable)
120{ 117{
121 struct i915_mmu_notifier *mn = 118 struct i915_mmu_notifier *mn =
122 container_of(_mn, struct i915_mmu_notifier, mn); 119 container_of(_mn, struct i915_mmu_notifier, mn);
123 struct i915_mmu_object *mo; 120 struct i915_mmu_object *mo;
124 struct interval_tree_node *it; 121 struct interval_tree_node *it;
125 LIST_HEAD(cancelled); 122 LIST_HEAD(cancelled);
123 unsigned long end;
126 124
127 if (RB_EMPTY_ROOT(&mn->objects.rb_root)) 125 if (RB_EMPTY_ROOT(&mn->objects.rb_root))
128 return 0; 126 return 0;
129 127
130 /* interval ranges are inclusive, but invalidate range is exclusive */ 128 /* interval ranges are inclusive, but invalidate range is exclusive */
131 end--; 129 end = range->end - 1;
132 130
133 spin_lock(&mn->lock); 131 spin_lock(&mn->lock);
134 it = interval_tree_iter_first(&mn->objects, start, end); 132 it = interval_tree_iter_first(&mn->objects, range->start, end);
135 while (it) { 133 while (it) {
136 if (!blockable) { 134 if (!range->blockable) {
137 spin_unlock(&mn->lock); 135 spin_unlock(&mn->lock);
138 return -EAGAIN; 136 return -EAGAIN;
139 } 137 }
@@ -151,7 +149,7 @@ static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
151 queue_work(mn->wq, &mo->work); 149 queue_work(mn->wq, &mo->work);
152 150
153 list_add(&mo->link, &cancelled); 151 list_add(&mo->link, &cancelled);
154 it = interval_tree_iter_next(it, start, end); 152 it = interval_tree_iter_next(it, range->start, end);
155 } 153 }
156 list_for_each_entry(mo, &cancelled, link) 154 list_for_each_entry(mo, &cancelled, link)
157 del_object(mo); 155 del_object(mo);
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c
index f8b35df44c60..b3019505065a 100644
--- a/drivers/gpu/drm/radeon/radeon_mn.c
+++ b/drivers/gpu/drm/radeon/radeon_mn.c
@@ -119,40 +119,38 @@ static void radeon_mn_release(struct mmu_notifier *mn,
119 * unmap them by move them into system domain again. 119 * unmap them by move them into system domain again.
120 */ 120 */
121static int radeon_mn_invalidate_range_start(struct mmu_notifier *mn, 121static int radeon_mn_invalidate_range_start(struct mmu_notifier *mn,
122 struct mm_struct *mm, 122 const struct mmu_notifier_range *range)
123 unsigned long start,
124 unsigned long end,
125 bool blockable)
126{ 123{
127 struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn); 124 struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn);
128 struct ttm_operation_ctx ctx = { false, false }; 125 struct ttm_operation_ctx ctx = { false, false };
129 struct interval_tree_node *it; 126 struct interval_tree_node *it;
127 unsigned long end;
130 int ret = 0; 128 int ret = 0;
131 129
132 /* notification is exclusive, but interval is inclusive */ 130 /* notification is exclusive, but interval is inclusive */
133 end -= 1; 131 end = range->end - 1;
134 132
135 /* TODO we should be able to split locking for interval tree and 133 /* TODO we should be able to split locking for interval tree and
136 * the tear down. 134 * the tear down.
137 */ 135 */
138 if (blockable) 136 if (range->blockable)
139 mutex_lock(&rmn->lock); 137 mutex_lock(&rmn->lock);
140 else if (!mutex_trylock(&rmn->lock)) 138 else if (!mutex_trylock(&rmn->lock))
141 return -EAGAIN; 139 return -EAGAIN;
142 140
143 it = interval_tree_iter_first(&rmn->objects, start, end); 141 it = interval_tree_iter_first(&rmn->objects, range->start, end);
144 while (it) { 142 while (it) {
145 struct radeon_mn_node *node; 143 struct radeon_mn_node *node;
146 struct radeon_bo *bo; 144 struct radeon_bo *bo;
147 long r; 145 long r;
148 146
149 if (!blockable) { 147 if (!range->blockable) {
150 ret = -EAGAIN; 148 ret = -EAGAIN;
151 goto out_unlock; 149 goto out_unlock;
152 } 150 }
153 151
154 node = container_of(it, struct radeon_mn_node, it); 152 node = container_of(it, struct radeon_mn_node, it);
155 it = interval_tree_iter_next(it, start, end); 153 it = interval_tree_iter_next(it, range->start, end);
156 154
157 list_for_each_entry(bo, &node->bos, mn_list) { 155 list_for_each_entry(bo, &node->bos, mn_list) {
158 156
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
index 9608681224e6..a4ec43093cb3 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -146,15 +146,12 @@ static int invalidate_range_start_trampoline(struct ib_umem_odp *item,
146} 146}
147 147
148static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn, 148static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn,
149 struct mm_struct *mm, 149 const struct mmu_notifier_range *range)
150 unsigned long start,
151 unsigned long end,
152 bool blockable)
153{ 150{
154 struct ib_ucontext_per_mm *per_mm = 151 struct ib_ucontext_per_mm *per_mm =
155 container_of(mn, struct ib_ucontext_per_mm, mn); 152 container_of(mn, struct ib_ucontext_per_mm, mn);
156 153
157 if (blockable) 154 if (range->blockable)
158 down_read(&per_mm->umem_rwsem); 155 down_read(&per_mm->umem_rwsem);
159 else if (!down_read_trylock(&per_mm->umem_rwsem)) 156 else if (!down_read_trylock(&per_mm->umem_rwsem))
160 return -EAGAIN; 157 return -EAGAIN;
@@ -169,9 +166,10 @@ static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn,
169 return 0; 166 return 0;
170 } 167 }
171 168
172 return rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, start, end, 169 return rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, range->start,
170 range->end,
173 invalidate_range_start_trampoline, 171 invalidate_range_start_trampoline,
174 blockable, NULL); 172 range->blockable, NULL);
175} 173}
176 174
177static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start, 175static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start,
@@ -182,9 +180,7 @@ static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start,
182} 180}
183 181
184static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn, 182static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn,
185 struct mm_struct *mm, 183 const struct mmu_notifier_range *range)
186 unsigned long start,
187 unsigned long end)
188{ 184{
189 struct ib_ucontext_per_mm *per_mm = 185 struct ib_ucontext_per_mm *per_mm =
190 container_of(mn, struct ib_ucontext_per_mm, mn); 186 container_of(mn, struct ib_ucontext_per_mm, mn);
@@ -192,8 +188,8 @@ static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn,
192 if (unlikely(!per_mm->active)) 188 if (unlikely(!per_mm->active))
193 return; 189 return;
194 190
195 rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, start, 191 rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, range->start,
196 end, 192 range->end,
197 invalidate_range_end_trampoline, true, NULL); 193 invalidate_range_end_trampoline, true, NULL);
198 up_read(&per_mm->umem_rwsem); 194 up_read(&per_mm->umem_rwsem);
199} 195}
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index 475b769e120c..14d2a90964c3 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -68,8 +68,7 @@ struct mmu_rb_handler {
68static unsigned long mmu_node_start(struct mmu_rb_node *); 68static unsigned long mmu_node_start(struct mmu_rb_node *);
69static unsigned long mmu_node_last(struct mmu_rb_node *); 69static unsigned long mmu_node_last(struct mmu_rb_node *);
70static int mmu_notifier_range_start(struct mmu_notifier *, 70static int mmu_notifier_range_start(struct mmu_notifier *,
71 struct mm_struct *, 71 const struct mmu_notifier_range *);
72 unsigned long, unsigned long, bool);
73static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, 72static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *,
74 unsigned long, unsigned long); 73 unsigned long, unsigned long);
75static void do_remove(struct mmu_rb_handler *handler, 74static void do_remove(struct mmu_rb_handler *handler,
@@ -284,10 +283,7 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
284} 283}
285 284
286static int mmu_notifier_range_start(struct mmu_notifier *mn, 285static int mmu_notifier_range_start(struct mmu_notifier *mn,
287 struct mm_struct *mm, 286 const struct mmu_notifier_range *range)
288 unsigned long start,
289 unsigned long end,
290 bool blockable)
291{ 287{
292 struct mmu_rb_handler *handler = 288 struct mmu_rb_handler *handler =
293 container_of(mn, struct mmu_rb_handler, mn); 289 container_of(mn, struct mmu_rb_handler, mn);
@@ -297,10 +293,11 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn,
297 bool added = false; 293 bool added = false;
298 294
299 spin_lock_irqsave(&handler->lock, flags); 295 spin_lock_irqsave(&handler->lock, flags);
300 for (node = __mmu_int_rb_iter_first(root, start, end - 1); 296 for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1);
301 node; node = ptr) { 297 node; node = ptr) {
302 /* Guard against node removal. */ 298 /* Guard against node removal. */
303 ptr = __mmu_int_rb_iter_next(node, start, end - 1); 299 ptr = __mmu_int_rb_iter_next(node, range->start,
300 range->end - 1);
304 trace_hfi1_mmu_mem_invalidate(node->addr, node->len); 301 trace_hfi1_mmu_mem_invalidate(node->addr, node->len);
305 if (handler->ops->invalidate(handler->ops_arg, node)) { 302 if (handler->ops->invalidate(handler->ops_arg, node)) {
306 __mmu_int_rb_remove(node, root); 303 __mmu_int_rb_remove(node, root);
diff --git a/drivers/misc/mic/scif/scif_dma.c b/drivers/misc/mic/scif/scif_dma.c
index 18b8ed57c4ac..e0d97044d0e9 100644
--- a/drivers/misc/mic/scif/scif_dma.c
+++ b/drivers/misc/mic/scif/scif_dma.c
@@ -201,23 +201,18 @@ static void scif_mmu_notifier_release(struct mmu_notifier *mn,
201} 201}
202 202
203static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, 203static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
204 struct mm_struct *mm, 204 const struct mmu_notifier_range *range)
205 unsigned long start,
206 unsigned long end,
207 bool blockable)
208{ 205{
209 struct scif_mmu_notif *mmn; 206 struct scif_mmu_notif *mmn;
210 207
211 mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier); 208 mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier);
212 scif_rma_destroy_tcw(mmn, start, end - start); 209 scif_rma_destroy_tcw(mmn, range->start, range->end - range->start);
213 210
214 return 0; 211 return 0;
215} 212}
216 213
217static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn, 214static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
218 struct mm_struct *mm, 215 const struct mmu_notifier_range *range)
219 unsigned long start,
220 unsigned long end)
221{ 216{
222 /* 217 /*
223 * Nothing to do here, everything needed was done in 218 * Nothing to do here, everything needed was done in
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
index 03b49d52092e..ca2032afe035 100644
--- a/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/drivers/misc/sgi-gru/grutlbpurge.c
@@ -220,9 +220,7 @@ void gru_flush_all_tlb(struct gru_state *gru)
220 * MMUOPS notifier callout functions 220 * MMUOPS notifier callout functions
221 */ 221 */
222static int gru_invalidate_range_start(struct mmu_notifier *mn, 222static int gru_invalidate_range_start(struct mmu_notifier *mn,
223 struct mm_struct *mm, 223 const struct mmu_notifier_range *range)
224 unsigned long start, unsigned long end,
225 bool blockable)
226{ 224{
227 struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, 225 struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
228 ms_notifier); 226 ms_notifier);
@@ -230,15 +228,14 @@ static int gru_invalidate_range_start(struct mmu_notifier *mn,
230 STAT(mmu_invalidate_range); 228 STAT(mmu_invalidate_range);
231 atomic_inc(&gms->ms_range_active); 229 atomic_inc(&gms->ms_range_active);
232 gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms, 230 gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms,
233 start, end, atomic_read(&gms->ms_range_active)); 231 range->start, range->end, atomic_read(&gms->ms_range_active));
234 gru_flush_tlb_range(gms, start, end - start); 232 gru_flush_tlb_range(gms, range->start, range->end - range->start);
235 233
236 return 0; 234 return 0;
237} 235}
238 236
239static void gru_invalidate_range_end(struct mmu_notifier *mn, 237static void gru_invalidate_range_end(struct mmu_notifier *mn,
240 struct mm_struct *mm, unsigned long start, 238 const struct mmu_notifier_range *range)
241 unsigned long end)
242{ 239{
243 struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, 240 struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
244 ms_notifier); 241 ms_notifier);
@@ -247,7 +244,8 @@ static void gru_invalidate_range_end(struct mmu_notifier *mn,
247 (void)atomic_dec_and_test(&gms->ms_range_active); 244 (void)atomic_dec_and_test(&gms->ms_range_active);
248 245
249 wake_up_all(&gms->ms_wait_queue); 246 wake_up_all(&gms->ms_wait_queue);
250 gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n", gms, start, end); 247 gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n",
248 gms, range->start, range->end);
251} 249}
252 250
253static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm) 251static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm)
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index b0b02a501167..5efc5eee9544 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -520,26 +520,26 @@ static int unmap_if_in_range(struct gntdev_grant_map *map,
520} 520}
521 521
522static int mn_invl_range_start(struct mmu_notifier *mn, 522static int mn_invl_range_start(struct mmu_notifier *mn,
523 struct mm_struct *mm, 523 const struct mmu_notifier_range *range)
524 unsigned long start, unsigned long end,
525 bool blockable)
526{ 524{
527 struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn); 525 struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn);
528 struct gntdev_grant_map *map; 526 struct gntdev_grant_map *map;
529 int ret = 0; 527 int ret = 0;
530 528
531 if (blockable) 529 if (range->blockable)
532 mutex_lock(&priv->lock); 530 mutex_lock(&priv->lock);
533 else if (!mutex_trylock(&priv->lock)) 531 else if (!mutex_trylock(&priv->lock))
534 return -EAGAIN; 532 return -EAGAIN;
535 533
536 list_for_each_entry(map, &priv->maps, next) { 534 list_for_each_entry(map, &priv->maps, next) {
537 ret = unmap_if_in_range(map, start, end, blockable); 535 ret = unmap_if_in_range(map, range->start, range->end,
536 range->blockable);
538 if (ret) 537 if (ret)
539 goto out_unlock; 538 goto out_unlock;
540 } 539 }
541 list_for_each_entry(map, &priv->freeable_maps, next) { 540 list_for_each_entry(map, &priv->freeable_maps, next) {
542 ret = unmap_if_in_range(map, start, end, blockable); 541 ret = unmap_if_in_range(map, range->start, range->end,
542 range->blockable);
543 if (ret) 543 if (ret)
544 goto out_unlock; 544 goto out_unlock;
545 } 545 }