FAILED: patch "[PATCH] drm/i915/userptr: Hold mmref whilst calling get-user-pages" failed to apply to 4.5-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.5-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
db9f9203e27495b2d151b695504e286eec026e9bMon Sep 17 00:00:00 2001
From: Chris Wilson <[email protected]>
Date: Tue, 5 Apr 2016 15:00:00 +0100
Subject: [PATCH] drm/i915/userptr: Hold mmref whilst calling get-user-pages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Holding a reference to the containing task_struct is not sufficient to prevent the mm_struct from being reaped under memory pressure. If this happens whilst we are calling get_user_pages(), explosions erupt - sometimes an immediate GPF, sometimes page flag corruption. To prevent the target mm from being reaped as we are reading from it, acquire a reference before we begin.
Testcase: igt/gem_shrink/*userptr
drivers/gpu/drm/i915/i915_gem_userptr.c +17 -12
@@ -501,19 +501,24 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)if (pvec !=NULL ) {struct mm_struct *mm = obj->userptr.mm->mm; -down_read (&mm->mmap_sem); -while (pinned < npages) { - ret =get_user_pages_remote (work->task, mm, - obj->userptr.ptr + pinned *PAGE_SIZE , - npages - pinned, - !obj->userptr.read_only,0 , - pvec + pinned,NULL ); -if (ret <0 ) -break ; - - pinned += ret; + ret = -EFAULT ; +if (atomic_inc_not_zero (&mm->mm_users)) { +down_read (&mm->mmap_sem); +while (pinned < npages) { + ret =get_user_pages_remote + (work->task, mm, + obj->userptr.ptr + pinned *PAGE_SIZE , + npages - pinned, + !obj->userptr.read_only,0 , + pvec + pinned,NULL ); +if (ret <0 ) +break ; + + pinned += ret; + } +up_read (&mm->mmap_sem); +mmput (mm); } -up_read (&mm->mmap_sem); }mutex_lock (&dev->struct_mutex);