diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-03-28 04:13:22 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-03-28 04:13:22 +0000 |
commit | 00862bb89cdf9ddd68c2e2e7f7d5caa8a8dd3128 (patch) | |
tree | c16b1dda5ce32b37114265e9924027c081dd9a95 /sys | |
parent | 94bf8d2acc2652a18a37150427397d63160f4f07 (diff) |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/i915/i915_active.c | 25 |
1 files 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); |