mirror of https://gitee.com/openkylin/linux.git
drm/i915/userptr: Handle unlocked gup retries
Enable gup to retry and fault the pages outside of the mmap_sem lock in
our worker. As we are inside our worker, outside of any critical path,
we can allow the mmap_sem lock to be dropped in order to service a page
fault; this in turn allows the mm to populate the page using a slow
fault handler.
References: 5b56d49fc3
("mm: add locked parameter to get_user_pages_remote()")
Testcase: igt/gem_userptr/userfault
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191111133205.11590-2-chris@chris-wilson.co.uk
This commit is contained in:
parent
0d4bbe3d40
commit
d323c9b882
|
@ -459,26 +459,31 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
|
||||||
if (pvec != NULL) {
|
if (pvec != NULL) {
|
||||||
struct mm_struct *mm = obj->userptr.mm->mm;
|
struct mm_struct *mm = obj->userptr.mm->mm;
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
|
int locked = 0;
|
||||||
|
|
||||||
if (!i915_gem_object_is_readonly(obj))
|
if (!i915_gem_object_is_readonly(obj))
|
||||||
flags |= FOLL_WRITE;
|
flags |= FOLL_WRITE;
|
||||||
|
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
if (mmget_not_zero(mm)) {
|
if (mmget_not_zero(mm)) {
|
||||||
down_read(&mm->mmap_sem);
|
|
||||||
while (pinned < npages) {
|
while (pinned < npages) {
|
||||||
|
if (!locked) {
|
||||||
|
down_read(&mm->mmap_sem);
|
||||||
|
locked = 1;
|
||||||
|
}
|
||||||
ret = get_user_pages_remote
|
ret = get_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,
|
||||||
flags,
|
flags,
|
||||||
pvec + pinned, NULL, NULL);
|
pvec + pinned, NULL, &locked);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pinned += ret;
|
pinned += ret;
|
||||||
}
|
}
|
||||||
up_read(&mm->mmap_sem);
|
if (locked)
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
mmput(mm);
|
mmput(mm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue