[Intel-gfx] [PATCH] drm/i915: Check i915_active wait status after flushing

Chris Wilson chris at chris-wilson.co.uk
Wed Jan 22 16:37:20 UTC 2020


Double check that the i915_active is finally idle after waiting, and
flushing its callback, just in case we need to re-activate it, for
example to keep the vma alive a bit longer due to last minute HW
activity (e.g. saving the context before unbinding).

Closes: https://gitlab.freedesktop.org/drm/intel/issues/530
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_active.c | 38 ++++++++++++++++++------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index ace55d5d4ca7..204564944dde 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -448,17 +448,11 @@ static void enable_signaling(struct i915_active_fence *active)
 	dma_fence_put(fence);
 }
 
-int i915_active_wait(struct i915_active *ref)
+static int flush_lazy_signals(struct i915_active *ref)
 {
 	struct active_node *it, *n;
 	int err = 0;
 
-	might_sleep();
-
-	if (!i915_active_acquire_if_busy(ref))
-		return 0;
-
-	/* Flush lazy signals */
 	enable_signaling(&ref->excl);
 	rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
 		if (is_barrier(&it->base)) /* unconnected idle barrier */
@@ -466,17 +460,31 @@ int i915_active_wait(struct i915_active *ref)
 
 		enable_signaling(&it->base);
 	}
-	/* Any fence added after the wait begins will not be auto-signaled */
 
-	i915_active_release(ref);
-	if (err)
-		return err;
+	return err;
+}
 
-	if (wait_var_event_interruptible(ref, i915_active_is_idle(ref)))
-		return -EINTR;
+int i915_active_wait(struct i915_active *ref)
+{
+	might_sleep();
 
-	flush_work(&ref->work);
-	return 0;
+	do {
+		int err;
+
+		if (!i915_active_acquire_if_busy(ref))
+			return 0;
+
+		/* Any fence added late will not be auto-signaled */
+		err = flush_lazy_signals(ref);
+		i915_active_release(ref);
+		if (err)
+			return err;
+
+		if (wait_var_event_interruptible(ref, i915_active_is_idle(ref)))
+			return -EINTR;
+
+		flush_work(&ref->work);
+	} while (1);
 }
 
 int i915_request_await_active(struct i915_request *rq, struct i915_active *ref)
-- 
2.25.0



More information about the Intel-gfx mailing list