From 34990bf9e2d81544639e6cff45b93d0e64a11fc7 Mon Sep 17 00:00:00 2001 From: jsg Date: Tue, 28 Mar 2023 04:13:21 +0000 Subject: [PATCH] drm/i915/active: Fix misuse of non-idle barriers as fence trackers From Janusz Krzysztofik 5c7591b8574c52c56b3994c2fbef1a3a311b5715 in linux-6.1.y/6.1.21 e0e6b416b25ee14716f3549e0cbec1011b193809 in mainline linux --- sys/dev/pci/drm/i915/i915_active.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/sys/dev/pci/drm/i915/i915_active.c b/sys/dev/pci/drm/i915/i915_active.c index d69fa195f0b..39c8e27e594 100644 --- a/sys/dev/pci/drm/i915/i915_active.c +++ b/sys/dev/pci/drm/i915/i915_active.c @@ -434,12 +434,12 @@ replace_barrier(struct i915_active *ref, struct i915_active_fence *active) * we can use it to substitute for the pending idle-barrer * request that we want to emit on the kernel_context. */ - __active_del_barrier(ref, node_from_active(active)); - return true; + return __active_del_barrier(ref, node_from_active(active)); } int i915_active_add_request(struct i915_active *ref, struct i915_request *rq) { + u64 idx = i915_request_timeline(rq)->fence_context; struct dma_fence *fence = &rq->fence; struct i915_active_fence *active; int err; @@ -449,16 +449,19 @@ int i915_active_add_request(struct i915_active *ref, struct i915_request *rq) if (err) return err; - active = active_instance(ref, i915_request_timeline(rq)->fence_context); - if (!active) { - err = -ENOMEM; - goto out; - } + do { + active = active_instance(ref, idx); + if (!active) { + err = -ENOMEM; + goto out; + } + + if (replace_barrier(ref, active)) { + RCU_INIT_POINTER(active->fence, NULL); + atomic_dec(&ref->count); + } + } while (unlikely(is_barrier(active))); - if (replace_barrier(ref, active)) { - RCU_INIT_POINTER(active->fence, NULL); - atomic_dec(&ref->count); - } if (!__i915_active_fence_set(active, fence)) __i915_active_acquire(ref); -- 2.20.1