Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index b0c1cc5fa917..0ae737871f84 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -71,6 +71,13 @@ static bool i915_gem_userptr_invalidate(struct mmu_interval_notifier *mni, mmu_interval_set_seq(mni, cur_seq); + /* drop the lazy reference we kept */ + if (!obj->userptr.page_ref && obj->userptr.pvec) { + unpin_user_pages(obj->userptr.pvec, obj->base.size >> PAGE_SHIFT); + kvfree(obj->userptr.pvec); + obj->userptr.pvec = NULL; + } + spin_unlock(&i915->mm.notifier_lock); /* we will unbind on next submission, still have userptr pins */ @@ -94,12 +101,12 @@ i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj) &i915_gem_userptr_notifier_ops); } -static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj) +static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj, bool free) { struct drm_i915_private *i915 = to_i915(obj->base.dev); spin_lock(&i915->mm.notifier_lock); - if (!--obj->userptr.page_ref) { + if (!--obj->userptr.page_ref && free) { const unsigned long num_pages = obj->base.size >> PAGE_SHIFT; unpin_user_pages(obj->userptr.pvec, num_pages); @@ -162,7 +169,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) return 0; err: - i915_gem_object_userptr_drop_ref(obj); + i915_gem_object_userptr_drop_ref(obj, true); err_free: kfree(st); return ret; @@ -220,7 +227,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, sg_free_table(pages); kfree(pages); - i915_gem_object_userptr_drop_ref(obj); + i915_gem_object_userptr_drop_ref(obj, true); } static int i915_gem_object_userptr_unbind(struct drm_i915_gem_object *obj, bool get_pages) @@ -320,10 +327,8 @@ int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj) } if (!obj->userptr.page_ref++) { - obj->userptr.pvec = pvec; + swap(obj->userptr.pvec, pvec); obj->userptr.notifier_seq = notifier_seq; - - pvec = NULL; } out_unlock: @@ -352,7 +357,7 @@ int i915_gem_object_userptr_submit_done(struct drm_i915_gem_object *obj) void i915_gem_object_userptr_submit_fini(struct drm_i915_gem_object *obj) { - i915_gem_object_userptr_drop_ref(obj); + i915_gem_object_userptr_drop_ref(obj, false); } static void @@ -360,6 +365,13 @@ i915_gem_userptr_release(struct drm_i915_gem_object *obj) { mmu_interval_notifier_remove(&obj->userptr.notifier); obj->userptr.notifier.mm = NULL; + GEM_WARN_ON(obj->userptr.page_ref); + + if (obj->userptr.pvec) { + unpin_user_pages(obj->userptr.pvec, obj->base.size >> PAGE_SHIFT); + kvfree(obj->userptr.pvec); + obj->userptr.pvec = NULL; + } } static int -- 2.28.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx