Re: [PATCH v2] drm/i915/userptr: Fix user pages leak on get_pages failure
Krzysztof Karas <[email protected]> Wed, 5 Aug 2026 06:12:19 +0000
| Newsgroups | gmane.comp.freedesktop.xorg.drivers.intel,gmane.comp.video.dri.devel,gmane.linux.kernel |
|---|---|
| Message-ID | <7zkpubrkbuxbygwwdd6a4db6swbckoaaujwjppsalhzoqvvl5r@4uk2j3xgvzym> |
Hi ZhaoJinming, On 2026-07-28 at 13:41:52 +0800, ZhaoJinming wrote: > When ____i915_gem_object_get_pages() fails inside > i915_gem_object_userptr_submit_init(), the pvec containing pages > pinned by pin_user_pages_fast() was never freed: > > 1. obj->userptr.pvec was set to the pinned pages > 2. The local pvec variable was NULLed > 3. ____i915_gem_object_get_pages() failed, but its internal > i915_gem_object_userptr_drop_ref() only decremented page_ref > from 2 to 1, not triggering the pvec cleanup > 4. The unconditional obj->userptr.page_ref-- brought page_ref > to 0, but the pinned pages remained referenced only by > obj->userptr.pvec with no path to reclaim them > > Additionally, the cache hit path could return success on a > subsequent call despite page_ref being 0, leading to a > GEM_BUG_ON(obj->userptr.page_ref < 0) crash in drop_ref when > the pages were eventually invalidated. > > Fix by calling i915_gem_object_userptr_drop_ref() on the > get_pages failure path, which properly decrements page_ref > from 1 to 0, triggering the pvec cleanup. Make the page_ref-- > after the if block conditional on success, since drop_ref > already handles the refcount on failure. Huh, so there was no cleanup on failure of ____i915_gem_object_get_pages, but the page_ref still got decremented. I think the changes below should be enough to resolve that issue, but we still need to run this through CI. > > Signed-off-by: ZhaoJinming <[email protected]> > --- > drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > index 043095f93ac6..7d2750528485 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > @@ -292,9 +292,12 @@ int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj) > obj->userptr.notifier_seq = notifier_seq; > pvec = NULL; > ret = ____i915_gem_object_get_pages(obj); > + if (ret) > + i915_gem_object_userptr_drop_ref(obj); > } > > - obj->userptr.page_ref--; > + if (!ret) > + obj->userptr.page_ref--; > > out_unlock: > i915_gem_object_unlock(obj); > -- > 2.20.1 > -- Best Regards, Krzysztof