Commit 3220c3b2 authored by Karol Herbst's avatar Karol Herbst Committed by Joonas Lahtinen

drm/i915: Fix race in __i915_vma_remove_closed

i915_vma_reopen checked if the vma is closed before without taking the
lock. So multiple threads could attempt removing the vma.

Instead the lock needs to be taken before actually checking.

v2: move struct declaration

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v5.3+
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5732Signed-off-by: default avatarKarol Herbst <kherbst@redhat.com>
Fixes: 155ab883 ("drm/i915: Move object close under its own lock")
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220420095720.3331609-1-kherbst@redhat.com
(cherry picked from commit 1df1c79c)
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent c5eb0a61
...@@ -1605,17 +1605,17 @@ void i915_vma_close(struct i915_vma *vma) ...@@ -1605,17 +1605,17 @@ void i915_vma_close(struct i915_vma *vma)
static void __i915_vma_remove_closed(struct i915_vma *vma) static void __i915_vma_remove_closed(struct i915_vma *vma)
{ {
struct intel_gt *gt = vma->vm->gt;
spin_lock_irq(&gt->closed_lock);
list_del_init(&vma->closed_link); list_del_init(&vma->closed_link);
spin_unlock_irq(&gt->closed_lock);
} }
void i915_vma_reopen(struct i915_vma *vma) void i915_vma_reopen(struct i915_vma *vma)
{ {
struct intel_gt *gt = vma->vm->gt;
spin_lock_irq(&gt->closed_lock);
if (i915_vma_is_closed(vma)) if (i915_vma_is_closed(vma))
__i915_vma_remove_closed(vma); __i915_vma_remove_closed(vma);
spin_unlock_irq(&gt->closed_lock);
} }
void i915_vma_release(struct kref *ref) void i915_vma_release(struct kref *ref)
...@@ -1641,6 +1641,7 @@ static void force_unbind(struct i915_vma *vma) ...@@ -1641,6 +1641,7 @@ static void force_unbind(struct i915_vma *vma)
static void release_references(struct i915_vma *vma) static void release_references(struct i915_vma *vma)
{ {
struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_gem_object *obj = vma->obj;
struct intel_gt *gt = vma->vm->gt;
GEM_BUG_ON(i915_vma_is_active(vma)); GEM_BUG_ON(i915_vma_is_active(vma));
...@@ -1650,7 +1651,9 @@ static void release_references(struct i915_vma *vma) ...@@ -1650,7 +1651,9 @@ static void release_references(struct i915_vma *vma)
rb_erase(&vma->obj_node, &obj->vma.tree); rb_erase(&vma->obj_node, &obj->vma.tree);
spin_unlock(&obj->vma.lock); spin_unlock(&obj->vma.lock);
spin_lock_irq(&gt->closed_lock);
__i915_vma_remove_closed(vma); __i915_vma_remove_closed(vma);
spin_unlock_irq(&gt->closed_lock);
__i915_vma_put(vma); __i915_vma_put(vma);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment