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 <[email protected]>
---
 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

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to