[Intel-gfx] [PATCH 03/14] drm/i915: Flush idle barriers when waiting
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Tue Feb 25 19:07:43 UTC 2020
On 24/02/2020 09:59, Chris Wilson wrote:
> If we do find ourselves with an idle barrier inside our active while
> waiting, attempt to flush it by emitting a pulse using the kernel
> context.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Steve Carbonari <steven.carbonari at intel.com>
> ---
> drivers/gpu/drm/i915/i915_active.c | 42 ++++++++++++++----
> drivers/gpu/drm/i915/selftests/i915_active.c | 46 ++++++++++++++++++++
> 2 files changed, 79 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
> index 9ccb931a733e..fae7e3820592 100644
> --- a/drivers/gpu/drm/i915/i915_active.c
> +++ b/drivers/gpu/drm/i915/i915_active.c
> @@ -7,6 +7,7 @@
> #include <linux/debugobjects.h>
>
> #include "gt/intel_context.h"
> +#include "gt/intel_engine_heartbeat.h"
> #include "gt/intel_engine_pm.h"
> #include "gt/intel_ring.h"
>
> @@ -460,26 +461,49 @@ static void enable_signaling(struct i915_active_fence *active)
> dma_fence_put(fence);
> }
>
> -int i915_active_wait(struct i915_active *ref)
> +static int flush_barrier(struct active_node *it)
> {
> - struct active_node *it, *n;
> - int err = 0;
> + struct intel_engine_cs *engine;
>
> - might_sleep();
> + if (!is_barrier(&it->base))
> + return 0;
>
> - if (!i915_active_acquire_if_busy(ref))
> + engine = __barrier_to_engine(it);
> + smp_rmb(); /* serialise with add_active_barriers */
> + if (!is_barrier(&it->base))
> return 0;
What is the purpose of the first !is_barrier check? Just to kind of look
better by not calling __bariier_to_engine on the wrong thing?
>
> - /* Flush lazy signals */
> + return intel_engine_flush_barriers(engine);
> +}
> +
> +static int flush_lazy_signals(struct i915_active *ref)
> +{
> + struct active_node *it, *n;
> + int err = 0;
> +
> enable_signaling(&ref->excl);
> rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
> - if (is_barrier(&it->base)) /* unconnected idle barrier */
> - continue;
> + err = flush_barrier(it); /* unconnected idle barrier? */
> + if (err)
> + break;
>
> enable_signaling(&it->base);
> }
> - /* Any fence added after the wait begins will not be auto-signaled */
>
> + return err;
> +}
> +
> +int i915_active_wait(struct i915_active *ref)
> +{
> + int err;
> +
> + might_sleep();
> +
> + if (!i915_active_acquire_if_busy(ref))
> + return 0;
> +
> + /* Any fence added after the wait begins will not be auto-signaled */
> + err = flush_lazy_signals(ref);
> i915_active_release(ref);
> if (err)
> return err;
> diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c
> index ef572a0c2566..067e30b8927f 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_active.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_active.c
> @@ -201,11 +201,57 @@ static int live_active_retire(void *arg)
> return err;
> }
>
> +static int live_active_barrier(void *arg)
> +{
> + struct drm_i915_private *i915 = arg;
> + struct intel_engine_cs *engine;
> + struct live_active *active;
> + int err = 0;
> +
> + /* Check that we get a callback when requests retire upon waiting */
> +
> + active = __live_alloc(i915);
> + if (!active)
> + return -ENOMEM;
> +
> + err = i915_active_acquire(&active->base);
> + if (err)
> + goto out;
> +
> + for_each_uabi_engine(engine, i915) {
> + err = i915_active_acquire_preallocate_barrier(&active->base,
> + engine);
> + if (err)
> + break;
> +
> + i915_active_acquire_barrier(&active->base);
> + }
> +
> + i915_active_release(&active->base);
> +
> + if (err == 0)
> + err = i915_active_wait(&active->base);
> +
> + if (err == 0 && !READ_ONCE(active->retired)) {
> + pr_err("i915_active not retired after flushing barriers!\n");
> + err = -EINVAL;
> + }
> +
> +out:
> + __live_put(active);
> +
> + if (igt_flush_test(i915))
> + err = -EIO;
> +
> + return err;
> +}
> +
> int i915_active_live_selftests(struct drm_i915_private *i915)
> {
> static const struct i915_subtest tests[] = {
> SUBTEST(live_active_wait),
> SUBTEST(live_active_retire),
> + SUBTEST(live_active_barrier),
> };
>
> if (intel_gt_is_wedged(&i915->gt))
>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Regards,
Tvrtko
More information about the Intel-gfx
mailing list