[Intel-gfx] [PATCH 2/2] drm/i915: Only emit one semaphore per request
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Tue Apr 2 12:36:02 UTC 2019
On 01/04/2019 16:57, Chris Wilson wrote:
> Ideally we only need one semaphore per ring to accommodate waiting on
> multiple engines in parallel. However, since we do not know which fences
> we will finally be waiting on, we emit a semaphore for every fence. It
> turns out to be quite easy to trick ourselves into exhausting our
> ringbuffer causing an error, just by feeding in a batch that depends on
> several thousand contexts.
>
> Since we never can be waiting on more than one semaphore in parallel
> (other than perhaps the desire to busywait on multiple engines), just
> pick the first fence for our semaphore. If we pick the wrong fence to
> busywait on, we just miss an opportunity to reduce latency.
>
> An adaption might be to use sched.flags as either a semaphore counter,
> or to track the first busywait on each engine, converting it back to a
> single use bit prior to closing the request.
>
> v2: Track first semaphore used per-engine (this caters for our basic
> igt that semaphores are working).
>
> Testcase: igt/gem_exec_fence/long-history
> Reported-by: Mika Kuoppala <mika.kuoppala at intel.com>
> Fixes: e88619646971 ("drm/i915: Use HW semaphores for inter-engine synchronisation on gen8+")
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Mika Kuoppala <mika.kuoppala at intel.com>
> ---
> drivers/gpu/drm/i915/i915_request.c | 13 +++++++++++--
> drivers/gpu/drm/i915/i915_scheduler.c | 5 +++--
> drivers/gpu/drm/i915/i915_scheduler_types.h | 3 ++-
> 3 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index e9c2094ab8ea..88a6d9968c15 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -783,6 +783,14 @@ emit_semaphore_wait(struct i915_request *to,
> GEM_BUG_ON(!from->timeline->has_initial_breadcrumb);
> GEM_BUG_ON(INTEL_GEN(to->i915) < 8);
>
> + BUILD_BUG_ON(sizeof(from->engine->mask) > sizeof(to->sched.semaphores));
> +
> + /* Just emit the first semaphore we see as request space is limited. */
> + if (to->sched.semaphores & from->engine->mask)
> + return i915_sw_fence_await_dma_fence(&to->submit,
> + &from->fence, 0,
> + I915_FENCE_GFP);
> +
> /* We need to pin the signaler's HWSP until we are finished reading. */
> err = i915_timeline_read_hwsp(from, to, &hwsp_offset);
> if (err)
> @@ -814,7 +822,8 @@ emit_semaphore_wait(struct i915_request *to,
> *cs++ = 0;
>
> intel_ring_advance(to, cs);
> - to->sched.flags |= I915_SCHED_HAS_SEMAPHORE;
> + to->sched.semaphores |= from->engine->mask;
> + to->sched.flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN;
> return 0;
> }
>
> @@ -1126,7 +1135,7 @@ void i915_request_add(struct i915_request *request)
> * far in the distance past over useful work, we keep a history
> * of any semaphore use along our dependency chain.
> */
> - if (!(request->sched.flags & I915_SCHED_HAS_SEMAPHORE))
> + if (!(request->sched.flags & I915_SCHED_HAS_SEMAPHORE_CHAIN))
> attr.priority |= I915_PRIORITY_NOSEMAPHORE;
>
> /*
> diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
> index e0f609d01564..77dbf7d74e12 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler.c
> +++ b/drivers/gpu/drm/i915/i915_scheduler.c
> @@ -41,6 +41,7 @@ void i915_sched_node_init(struct i915_sched_node *node)
> INIT_LIST_HEAD(&node->waiters_list);
> INIT_LIST_HEAD(&node->link);
> node->attr.priority = I915_PRIORITY_INVALID;
> + node->semaphores = 0;
> node->flags = 0;
> }
>
> @@ -73,9 +74,9 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
> dep->flags = flags;
>
> /* Keep track of whether anyone on this chain has a semaphore */
> - if (signal->flags & I915_SCHED_HAS_SEMAPHORE &&
> + if (signal->flags & I915_SCHED_HAS_SEMAPHORE_CHAIN &&
> !node_started(signal))
> - node->flags |= I915_SCHED_HAS_SEMAPHORE;
> + node->flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN;
>
> ret = true;
> }
> diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h
> index 5c94b3eb5c81..aa3aeae5404a 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler_types.h
> +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h
> @@ -76,7 +76,8 @@ struct i915_sched_node {
> struct list_head link;
> struct i915_sched_attr attr;
> unsigned int flags;
> -#define I915_SCHED_HAS_SEMAPHORE BIT(0)
> +#define I915_SCHED_HAS_SEMAPHORE_CHAIN BIT(0)
> + unsigned int semaphores; /* intel_engine_mask_t */
But can't use the type yet?
> };
>
> struct i915_dependency {
>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Regards,
Tvrtko
More information about the Intel-gfx
mailing list