forked from mirrors/linux
		
	drm/i915: convert get_user_pages() --> pin_user_pages()
This code was using get_user_pages*(), in a "Case 2" scenario (DMA/RDMA),
using the categorization from [1].  That means that it's time to convert
the get_user_pages*() + put_page() calls to pin_user_pages*() +
unpin_user_pages() calls.
There is some helpful background in [2]: basically, this is a small part
of fixing a long-standing disconnect between pinning pages, and file
systems' use of those pages.
[1] Documentation/core-api/pin_user_pages.rst
[2] "Explicit pinning of user-space pages":
    https://lwn.net/Articles/807108/
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Souptick Joarder <jrdr.linux@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: "Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Link: http://lkml.kernel.org/r/20200519002124.2025955-5-jhubbard@nvidia.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									104acc3276
								
							
						
					
					
						commit
						2170ecfa76
					
				
					 1 changed files with 13 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -471,7 +471,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
 | 
			
		|||
					down_read(&mm->mmap_sem);
 | 
			
		||||
					locked = 1;
 | 
			
		||||
				}
 | 
			
		||||
				ret = get_user_pages_remote
 | 
			
		||||
				ret = pin_user_pages_remote
 | 
			
		||||
					(work->task, mm,
 | 
			
		||||
					 obj->userptr.ptr + pinned * PAGE_SIZE,
 | 
			
		||||
					 npages - pinned,
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
 | 
			
		|||
	}
 | 
			
		||||
	mutex_unlock(&obj->mm.lock);
 | 
			
		||||
 | 
			
		||||
	release_pages(pvec, pinned);
 | 
			
		||||
	unpin_user_pages(pvec, pinned);
 | 
			
		||||
	kvfree(pvec);
 | 
			
		||||
 | 
			
		||||
	i915_gem_object_put(obj);
 | 
			
		||||
| 
						 | 
				
			
			@ -564,6 +564,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 | 
			
		|||
	struct sg_table *pages;
 | 
			
		||||
	bool active;
 | 
			
		||||
	int pinned;
 | 
			
		||||
	unsigned int gup_flags = 0;
 | 
			
		||||
 | 
			
		||||
	/* If userspace should engineer that these pages are replaced in
 | 
			
		||||
	 * the vma between us binding this page into the GTT and completion
 | 
			
		||||
| 
						 | 
				
			
			@ -606,12 +607,15 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 | 
			
		|||
		 *
 | 
			
		||||
		 * We may or may not care.
 | 
			
		||||
		 */
 | 
			
		||||
		if (pvec) /* defer to worker if malloc fails */
 | 
			
		||||
			pinned = __get_user_pages_fast(obj->userptr.ptr,
 | 
			
		||||
						       num_pages,
 | 
			
		||||
						       !i915_gem_object_is_readonly(obj),
 | 
			
		||||
		if (pvec) {
 | 
			
		||||
			/* defer to worker if malloc fails */
 | 
			
		||||
			if (!i915_gem_object_is_readonly(obj))
 | 
			
		||||
				gup_flags |= FOLL_WRITE;
 | 
			
		||||
			pinned = pin_user_pages_fast_only(obj->userptr.ptr,
 | 
			
		||||
							  num_pages, gup_flags,
 | 
			
		||||
							  pvec);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	active = false;
 | 
			
		||||
	if (pinned < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +632,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 | 
			
		|||
		__i915_gem_userptr_set_active(obj, true);
 | 
			
		||||
 | 
			
		||||
	if (IS_ERR(pages))
 | 
			
		||||
		release_pages(pvec, pinned);
 | 
			
		||||
		unpin_user_pages(pvec, pinned);
 | 
			
		||||
	kvfree(pvec);
 | 
			
		||||
 | 
			
		||||
	return PTR_ERR_OR_ZERO(pages);
 | 
			
		||||
| 
						 | 
				
			
			@ -683,7 +687,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj,
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		mark_page_accessed(page);
 | 
			
		||||
		put_page(page);
 | 
			
		||||
		unpin_user_page(page);
 | 
			
		||||
	}
 | 
			
		||||
	obj->mm.dirty = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue