summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2023-03-28 04:13:22 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2023-03-28 04:13:22 +0000
commit00862bb89cdf9ddd68c2e2e7f7d5caa8a8dd3128 (patch)
treec16b1dda5ce32b37114265e9924027c081dd9a95 /sys
parent94bf8d2acc2652a18a37150427397d63160f4f07 (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.c25
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);