summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/selftests
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-11-01 18:10:22 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-11-02 08:34:53 +0000
commit38813767c7c5d9f8e0bd6b14136add861cc79b33 (patch)
treebc787670a1b6d3655366f195905c7c19642b8c56 /drivers/gpu/drm/i915/selftests
parent9278bbb6e43cde306f07f9a60274195b5b24f90a (diff)
downloadlinux-stable-38813767c7c5d9f8e0bd6b14136add861cc79b33.tar.gz
linux-stable-38813767c7c5d9f8e0bd6b14136add861cc79b33.tar.bz2
linux-stable-38813767c7c5d9f8e0bd6b14136add861cc79b33.zip
drm/i915/selftests: Flush all active callbacks
Flushing the outer i915_active is not enough, as we need the barrier to be applied across all the active dma_fence callbacks. So we must serialise with each outstanding fence. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112096 References: f79520bb3337 ("drm/i915/selftests: Synchronize checking active status with retirement") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Andi Shyti <andi.shyti@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191101181022.25633-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/selftests')
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_active.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c
index 260b0ee5d1e3..f3fa05c78d78 100644
--- a/drivers/gpu/drm/i915/selftests/i915_active.c
+++ b/drivers/gpu/drm/i915/selftests/i915_active.c
@@ -250,3 +250,36 @@ void i915_active_print(struct i915_active *ref, struct drm_printer *m)
i915_active_release(ref);
}
}
+
+static void spin_unlock_wait(spinlock_t *lock)
+{
+ spin_lock_irq(lock);
+ spin_unlock_irq(lock);
+}
+
+void i915_active_unlock_wait(struct i915_active *ref)
+{
+ if (i915_active_acquire_if_busy(ref)) {
+ struct active_node *it, *n;
+
+ rcu_read_lock();
+ rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
+ struct dma_fence *f;
+
+ /* Wait for all active callbacks */
+ f = rcu_dereference(it->base.fence);
+ if (f)
+ spin_unlock_wait(f->lock);
+ }
+ rcu_read_unlock();
+
+ i915_active_release(ref);
+ }
+
+ /* And wait for the retire callback */
+ mutex_lock(&ref->mutex);
+ mutex_unlock(&ref->mutex);
+
+ /* ... which may have been on a thread instead */
+ flush_work(&ref->work);
+}