Commit e766fde6 authored by Chris Wilson's avatar Chris Wilson Committed by Joonas Lahtinen

drm/i915: Delay semaphore submission until the start of the signaler

Currently we submit the semaphore busywait as soon as the signaler is
submitted to HW. However, we may submit the signaler as the tail of a
batch of requests, and even not as the first context in the HW list,
i.e. the busywait may start spinning far in advance of the signaler even
starting.

If we wait until the request before the signaler is completed before
submitting the busywait, we prevent the busywait from starting too
early, if the signaler is not first in submission port.

To handle the case where the signaler is at the start of the second (or
later) submission port, we will need to delay the execution callback
until we know the context is promoted to port0. A challenge for later.

Fixes: e8861964 ("drm/i915: Use HW semaphores for inter-engine synchronisation on gen8+")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190501114541.10077-9-chris@chris-wilson.co.uk
(cherry picked from commit 0d90ccb7)
[Joonas: edited Fixes: tag into single line.]
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 9628e15c
......@@ -798,6 +798,21 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
return ERR_PTR(ret);
}
static int
i915_request_await_start(struct i915_request *rq, struct i915_request *signal)
{
if (list_is_first(&signal->ring_link, &signal->ring->request_list))
return 0;
signal = list_prev_entry(signal, ring_link);
if (i915_timeline_sync_is_later(rq->timeline, &signal->fence))
return 0;
return i915_sw_fence_await_dma_fence(&rq->submit,
&signal->fence, 0,
I915_FENCE_GFP);
}
static int
emit_semaphore_wait(struct i915_request *to,
struct i915_request *from,
......@@ -816,6 +831,10 @@ emit_semaphore_wait(struct i915_request *to,
&from->fence, 0,
I915_FENCE_GFP);
err = i915_request_await_start(to, from);
if (err < 0)
return err;
err = i915_sw_fence_await_dma_fence(&to->semaphore,
&from->fence, 0,
I915_FENCE_GFP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment