mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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);
 | 
										down_read(&mm->mmap_sem);
 | 
				
			||||||
					locked = 1;
 | 
										locked = 1;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				ret = get_user_pages_remote
 | 
									ret = pin_user_pages_remote
 | 
				
			||||||
					(work->task, mm,
 | 
										(work->task, mm,
 | 
				
			||||||
					 obj->userptr.ptr + pinned * PAGE_SIZE,
 | 
										 obj->userptr.ptr + pinned * PAGE_SIZE,
 | 
				
			||||||
					 npages - pinned,
 | 
										 npages - pinned,
 | 
				
			||||||
| 
						 | 
					@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&obj->mm.lock);
 | 
						mutex_unlock(&obj->mm.lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	release_pages(pvec, pinned);
 | 
						unpin_user_pages(pvec, pinned);
 | 
				
			||||||
	kvfree(pvec);
 | 
						kvfree(pvec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i915_gem_object_put(obj);
 | 
						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;
 | 
						struct sg_table *pages;
 | 
				
			||||||
	bool active;
 | 
						bool active;
 | 
				
			||||||
	int pinned;
 | 
						int pinned;
 | 
				
			||||||
 | 
						unsigned int gup_flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If userspace should engineer that these pages are replaced in
 | 
						/* If userspace should engineer that these pages are replaced in
 | 
				
			||||||
	 * the vma between us binding this page into the GTT and completion
 | 
						 * 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.
 | 
							 * We may or may not care.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (pvec) /* defer to worker if malloc fails */
 | 
							if (pvec) {
 | 
				
			||||||
			pinned = __get_user_pages_fast(obj->userptr.ptr,
 | 
								/* defer to worker if malloc fails */
 | 
				
			||||||
						       num_pages,
 | 
								if (!i915_gem_object_is_readonly(obj))
 | 
				
			||||||
						       !i915_gem_object_is_readonly(obj),
 | 
									gup_flags |= FOLL_WRITE;
 | 
				
			||||||
 | 
								pinned = pin_user_pages_fast_only(obj->userptr.ptr,
 | 
				
			||||||
 | 
												  num_pages, gup_flags,
 | 
				
			||||||
							  pvec);
 | 
												  pvec);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	active = false;
 | 
						active = false;
 | 
				
			||||||
	if (pinned < 0) {
 | 
						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);
 | 
							__i915_gem_userptr_set_active(obj, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (IS_ERR(pages))
 | 
						if (IS_ERR(pages))
 | 
				
			||||||
		release_pages(pvec, pinned);
 | 
							unpin_user_pages(pvec, pinned);
 | 
				
			||||||
	kvfree(pvec);
 | 
						kvfree(pvec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return PTR_ERR_OR_ZERO(pages);
 | 
						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);
 | 
							mark_page_accessed(page);
 | 
				
			||||||
		put_page(page);
 | 
							unpin_user_page(page);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	obj->mm.dirty = false;
 | 
						obj->mm.dirty = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue