[Intel-gfx] [PATCH v3 63/63] drm/i915: Keep lazy reference to userptr pages
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Thu Oct 15 11:26:27 UTC 2020
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
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
More information about the Intel-gfx
mailing list