Thomas Zimmermann c29d39
From 8cf97637ff8891be040bac37b96dd97e5996ca93 Mon Sep 17 00:00:00 2001
Thomas Zimmermann c29d39
From: Daniel Vetter <daniel.vetter@ffwll.ch>
Thomas Zimmermann c29d39
Date: Thu, 2 Sep 2021 16:20:49 +0200
Thomas Zimmermann c29d39
Subject: drm/i915: Keep gem ctx->vm alive until the final put
Thomas Zimmermann c29d39
MIME-Version: 1.0
Thomas Zimmermann c29d39
Content-Type: text/plain; charset=UTF-8
Thomas Zimmermann c29d39
Content-Transfer-Encoding: 8bit
Thomas Zimmermann c29d39
Git-commit: 8cf97637ff8891be040bac37b96dd97e5996ca93
Thomas Zimmermann c29d39
Patch-mainline: v5.16-rc1
Thomas Zimmermann c29d39
References: bsc#1152489
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
The comment added in
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    commit b81dde719439c8f09bb61e742ed95bfc4b33946b
Thomas Zimmermann c29d39
    Author: Chris Wilson <chris@chris-wilson.co.uk>
Thomas Zimmermann c29d39
__    Date:   Tue May 21 22:11:29 2019 +0100
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
        drm/i915: Allow userspace to clone contexts on creation
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
and moved in
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    commit 27dbae8f36c1c25008b7885fc07c57054b7dfba3
Thomas Zimmermann c29d39
    Author: Chris Wilson <chris@chris-wilson.co.uk>
Thomas Zimmermann c29d39
__    Date:   Wed Nov 6 09:13:12 2019 +0000
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
        drm/i915/gem: Safely acquire the ctx->vm when copying
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
suggested that i915_address_space were at least intended to be managed
Thomas Zimmermann c29d39
through SLAB_TYPESAFE_BY_RCU:
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
                * This ppgtt may have be reallocated between
Thomas Zimmermann c29d39
                * the read and the kref, and reassigned to a third
Thomas Zimmermann c29d39
                * context. In order to avoid inadvertent sharing
Thomas Zimmermann c29d39
                * of this ppgtt with that third context (and not
Thomas Zimmermann c29d39
                * src), we have to confirm that we have the same
Thomas Zimmermann c29d39
                * ppgtt after passing through the strong memory
Thomas Zimmermann c29d39
                * barrier implied by a successful
Thomas Zimmermann c29d39
                * kref_get_unless_zero().
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
But extensive git history search has not brough any such reuse to
Thomas Zimmermann c29d39
light.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
What has come to light though is that ever since
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
commit 2850748ef8763ab46958e43a4d1c445f29eeb37d
Thomas Zimmermann c29d39
Author: Chris Wilson <chris@chris-wilson.co.uk>
Thomas Zimmermann c29d39
__Date:   Fri Oct 4 14:39:58 2019 +0100
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    drm/i915: Pull i915_vma_pin under the vm->mutex
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
(yes this commit is earlier) the final i915_vma_put call has been
Thomas Zimmermann c29d39
moved from i915_gem_context_free (now called _release) to
Thomas Zimmermann c29d39
context_close, which means it's not actually safe anymore to access
Thomas Zimmermann c29d39
the ctx->vm pointer without lock helds, because it might disappear at
Thomas Zimmermann c29d39
any moment. Note that superficially things all still work, because the
Thomas Zimmermann c29d39
i915_address_space is RCU protected since
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    commit b32fa811156328aea5a3c2ff05cc096490382456
Thomas Zimmermann c29d39
    Author: Chris Wilson <chris@chris-wilson.co.uk>
Thomas Zimmermann c29d39
__    Date:   Thu Jun 20 19:37:05 2019 +0100
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
        drm/i915/gtt: Defer address space cleanup to an RCU worker
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
except the very clever macro above (which is designed to protected
Thomas Zimmermann c29d39
against object reuse due to SLAB_TYPESAFE_BY_RCU or similar tricks)
Thomas Zimmermann c29d39
results in an endless loop if the refcount of the ctx->vm ever
Thomas Zimmermann c29d39
permanently drops to 0. Which it totally now can.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
Fix that by moving the final i915_vm_put to where it should be.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
Note that i915_gem_context is rcu protected, but _only_ the final
Thomas Zimmermann c29d39
kfree. This means anyone who chases a pointer to a gem ctx solely
Thomas Zimmermann c29d39
under the protection can pretty only call kref_get_unless_zero(). This
Thomas Zimmermann c29d39
seems to be pretty much the case, aside from a bunch of cases that
Thomas Zimmermann c29d39
consult the scheduling information without any further protection.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thomas Zimmermann c29d39
Cc: Jason Ekstrand <jason@jlekstrand.net>
Thomas Zimmermann c29d39
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Thomas Zimmermann c29d39
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Thomas Zimmermann c29d39
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Thomas Zimmermann c29d39
Cc: Matthew Brost <matthew.brost@intel.com>
Thomas Zimmermann c29d39
Cc: Matthew Auld <matthew.auld@intel.com>
Thomas Zimmermann c29d39
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thomas Zimmermann c29d39
Cc: "Thomas Hellström" <thomas.hellstrom@intel.com>
Thomas Zimmermann c29d39
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Thomas Zimmermann c29d39
Cc: Dave Airlie <airlied@redhat.com>
Thomas Zimmermann c29d39
Fixes: 2850748ef876 ("drm/i915: Pull i915_vma_pin under the vm->mutex")
Thomas Zimmermann c29d39
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Thomas Zimmermann c29d39
Link: https://patchwork.freedesktop.org/patch/msgid/20210902142057.929669-3-daniel.vetter@ffwll.ch
Thomas Zimmermann c29d39
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Thomas Zimmermann c29d39
---
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
A message from ksd-import-patch:
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    Hello dear friend,
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    I'm ksd-import-patch, the tool that imported this patch
Thomas Zimmermann c29d39
    file.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    I had to prefix at least one line in the commit message
Thomas Zimmermann c29d39
    with __ to work around a bug in the commit hook of
Thomas Zimmermann c29d39
    kernel-sources, which thinks the line contains a patch
Thomas Zimmermann c29d39
    tag.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    If you think the patch should have been merged as it is
Thomas Zimmermann c29d39
    in upstream, please send this file via email to
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
            kernel-cvs@suse.de
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    and request the problem to be fixed.
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
    Yours truely,
Thomas Zimmermann c29d39
            ksd-import-patch
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
---
Thomas Zimmermann c29d39
 drivers/gpu/drm/i915/gem/i915_gem_context.c |   15 ++++++++++++++-
Thomas Zimmermann c29d39
 1 file changed, 14 insertions(+), 1 deletion(-)
Thomas Zimmermann c29d39
Thomas Zimmermann c29d39
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
Thomas Zimmermann c29d39
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
Thomas Zimmermann c29d39
@@ -335,12 +335,18 @@ static struct i915_gem_engines *default_
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
 static void i915_gem_context_free(struct i915_gem_context *ctx)
Thomas Zimmermann c29d39
 {
Thomas Zimmermann c29d39
+	struct i915_address_space *vm;
Thomas Zimmermann c29d39
+
Thomas Zimmermann c29d39
 	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
 	spin_lock(&ctx->i915->gem.contexts.lock);
Thomas Zimmermann c29d39
 	list_del(&ctx->link);
Thomas Zimmermann c29d39
 	spin_unlock(&ctx->i915->gem.contexts.lock);
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
+	vm = i915_gem_context_vm(ctx);
Thomas Zimmermann c29d39
+	if (vm)
Thomas Zimmermann c29d39
+		i915_vm_put(vm);
Thomas Zimmermann c29d39
+
Thomas Zimmermann c29d39
 	mutex_destroy(&ctx->engines_mutex);
Thomas Zimmermann c29d39
 	mutex_destroy(&ctx->lut_mutex);
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
@@ -607,8 +613,15 @@ static void context_close(struct i915_ge
Thomas Zimmermann c29d39
 	set_closed_name(ctx);
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
 	vm = i915_gem_context_vm(ctx);
Thomas Zimmermann c29d39
-	if (vm)
Thomas Zimmermann c29d39
+	if (vm) {
Thomas Zimmermann c29d39
+		/* i915_vm_close drops the final reference, which is a bit too
Thomas Zimmermann c29d39
+		 * early and could result in surprises with concurrent
Thomas Zimmermann c29d39
+		 * operations racing with thist ctx close. Keep a full reference
Thomas Zimmermann c29d39
+		 * until the end.
Thomas Zimmermann c29d39
+		 */
Thomas Zimmermann c29d39
+		i915_vm_get(vm);
Thomas Zimmermann c29d39
 		i915_vm_close(vm);
Thomas Zimmermann c29d39
+	}
Thomas Zimmermann c29d39
 
Thomas Zimmermann c29d39
 	ctx->file_priv = ERR_PTR(-EBADF);
Thomas Zimmermann c29d39