aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaarten Lankhorst <[email protected]>2021-03-23 16:50:51 +0100
committerDaniel Vetter <[email protected]>2021-03-24 17:48:11 +0100
commitfd995a3cc432da2d18c28c2731f41da9b751897b (patch)
tree3165b6ce74c7c0de10cc663a92a82c6141075f86
parentcf41a8f1dc1e471a378a1a0c46d72e2fbe7598d6 (diff)
drm/i915: Keep userpointer bindings if seqcount is unchanged, v2.
Instead of force unbinding and rebinding every time, we try to check if our notifier seqcount is still correct when pages are bound. This way we only rebind userptr when we need to, and prevent stalls. Changes since v1: - Missing mutex_unlock, reported by kbuild. Reported-by: kernel test robot <[email protected]> Reported-by: Dan Carpenter <[email protected]> Reviewed-by: Thomas Hellström <[email protected]> Signed-off-by: Maarten Lankhorst <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_userptr.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 4afd08c1fe09..8ebdd252d6b8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -281,12 +281,33 @@ int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj)
if (ret)
return ret;
- /* Make sure userptr is unbound for next attempt, so we don't use stale pages. */
- ret = i915_gem_object_userptr_unbind(obj, false);
+ /* optimistically try to preserve current pages while unlocked */
+ if (i915_gem_object_has_pages(obj) &&
+ !mmu_interval_check_retry(&obj->userptr.notifier,
+ obj->userptr.notifier_seq)) {
+ spin_lock(&i915->mm.notifier_lock);
+ if (obj->userptr.pvec &&
+ !mmu_interval_read_retry(&obj->userptr.notifier,
+ obj->userptr.notifier_seq)) {
+ obj->userptr.page_ref++;
+
+ /* We can keep using the current binding, this is the fastpath */
+ ret = 1;
+ }
+ spin_unlock(&i915->mm.notifier_lock);
+ }
+
+ if (!ret) {
+ /* Make sure userptr is unbound for next attempt, so we don't use stale pages. */
+ ret = i915_gem_object_userptr_unbind(obj, false);
+ }
i915_gem_object_unlock(obj);
- if (ret)
+ if (ret < 0)
return ret;
+ if (ret > 0)
+ return 0;
+
notifier_seq = mmu_interval_read_begin(&obj->userptr.notifier);
pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL);