From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2] drm/i915/execlists: Track begin/end of execlists submission sequences
Date: Tue, 03 Apr 2018 14:17:57 +0300 [thread overview]
Message-ID: <87po3g35ei.fsf@gaia.fi.intel.com> (raw)
In-Reply-To: <20180331130626.10712-1-chris@chris-wilson.co.uk>
Chris Wilson <chris@chris-wilson.co.uk> writes:
> We would like to start doing some bookkeeping at the beginning, between
> contexts and at the end of execlists submission. We already mark the
> beginning and end using EXECLISTS_ACTIVE_USER, to provide an indication
> when the HW is idle. This give us a pair of sequence points we can then
> expand on for further bookkeeping.
>
> v2: Refactor guc submission to share the same begin/end.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Cc: Francisco Jerez <currojerez@riseup.net>
> Reviewed-by: Francisco Jerez <currojerez@riseup.net> #v1
> ---
> drivers/gpu/drm/i915/intel_guc_submission.c | 17 ++++++----
> drivers/gpu/drm/i915/intel_lrc.c | 50 ++++++++++++++++++++++-------
> drivers/gpu/drm/i915/intel_ringbuffer.h | 15 ++++++++-
> 3 files changed, 63 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
> index 207cda062626..749f27916a02 100644
> --- a/drivers/gpu/drm/i915/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/intel_guc_submission.c
> @@ -728,7 +728,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
> execlists->first = rb;
> if (submit) {
> port_assign(port, last);
> - execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
> + execlists_user_begin(execlists, execlists->port);
> guc_submit(engine);
> }
>
> @@ -748,17 +748,20 @@ static void guc_submission_tasklet(unsigned long data)
> struct execlist_port *port = execlists->port;
> struct i915_request *rq;
>
> - rq = port_request(&port[0]);
> + rq = port_request(port);
> while (rq && i915_request_completed(rq)) {
> trace_i915_request_out(rq);
> i915_request_put(rq);
>
> - execlists_port_complete(execlists, port);
> -
> - rq = port_request(&port[0]);
> + port = execlists_port_complete(execlists, port);
> + if (port_isset(port)) {
> + execlists_user_begin(execlists, port);
> + rq = port_request(port);
> + } else {
> + execlists_user_end(execlists);
> + rq = NULL;
I did ponder doing the user_begin/end pair in complete
but better not to hide it in there as we might end up
doing completes without notifying users.
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> + }
> }
> - if (!rq)
> - execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
>
> if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) &&
> intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) ==
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index f60b61bf8b3b..4d08875422b6 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -374,6 +374,19 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status)
> status, rq);
> }
>
> +inline void
> +execlists_user_begin(struct intel_engine_execlists *execlists,
> + const struct execlist_port *port)
> +{
> + execlists_set_active_once(execlists, EXECLISTS_ACTIVE_USER);
> +}
> +
> +inline void
> +execlists_user_end(struct intel_engine_execlists *execlists)
> +{
> + execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
> +}
> +
> static inline void
> execlists_context_schedule_in(struct i915_request *rq)
> {
> @@ -711,7 +724,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> spin_unlock_irq(&engine->timeline->lock);
>
> if (submit) {
> - execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
> + execlists_user_begin(execlists, execlists->port);
> execlists_submit_ports(engine);
> }
>
> @@ -742,7 +755,7 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
> port++;
> }
>
> - execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
> + execlists_user_end(execlists);
> }
>
> static void clear_gtiir(struct intel_engine_cs *engine)
> @@ -873,7 +886,7 @@ static void execlists_submission_tasklet(unsigned long data)
> {
> struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
> struct intel_engine_execlists * const execlists = &engine->execlists;
> - struct execlist_port * const port = execlists->port;
> + struct execlist_port *port = execlists->port;
> struct drm_i915_private *dev_priv = engine->i915;
> bool fw = false;
>
> @@ -1012,10 +1025,28 @@ static void execlists_submission_tasklet(unsigned long data)
>
> GEM_BUG_ON(count == 0);
> if (--count == 0) {
> + /*
> + * On the final event corresponding to the
> + * submission of this context, we expect either
> + * an element-switch event or a completion
> + * event (and on completion, the active-idle
> + * marker). No more preemptions, lite-restore
> + * or otherwise.
> + */
> GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED);
> GEM_BUG_ON(port_isset(&port[1]) &&
> !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH));
> + GEM_BUG_ON(!port_isset(&port[1]) &&
> + !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
> +
> + /*
> + * We rely on the hardware being strongly
> + * ordered, that the breadcrumb write is
> + * coherent (visible from the CPU) before the
> + * user interrupt and CSB is processed.
> + */
> GEM_BUG_ON(!i915_request_completed(rq));
> +
> execlists_context_schedule_out(rq);
> trace_i915_request_out(rq);
> i915_request_put(rq);
> @@ -1023,17 +1054,14 @@ static void execlists_submission_tasklet(unsigned long data)
> GEM_TRACE("%s completed ctx=%d\n",
> engine->name, port->context_id);
>
> - execlists_port_complete(execlists, port);
> + port = execlists_port_complete(execlists, port);
> + if (port_isset(port))
> + execlists_user_begin(execlists, port);
> + else
> + execlists_user_end(execlists);
> } else {
> port_set(port, port_pack(rq, count));
> }
> -
> - /* After the final element, the hw should be idle */
> - GEM_BUG_ON(port_count(port) == 0 &&
> - !(status & GEN8_CTX_STATUS_ACTIVE_IDLE));
> - if (port_count(port) == 0)
> - execlists_clear_active(execlists,
> - EXECLISTS_ACTIVE_USER);
> }
>
> if (head != execlists->csb_head) {
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index a02c7b3b9d55..40461e29cdab 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -638,6 +638,13 @@ execlists_set_active(struct intel_engine_execlists *execlists,
> __set_bit(bit, (unsigned long *)&execlists->active);
> }
>
> +static inline bool
> +execlists_set_active_once(struct intel_engine_execlists *execlists,
> + unsigned int bit)
> +{
> + return !__test_and_set_bit(bit, (unsigned long *)&execlists->active);
> +}
> +
> static inline void
> execlists_clear_active(struct intel_engine_execlists *execlists,
> unsigned int bit)
> @@ -652,6 +659,10 @@ execlists_is_active(const struct intel_engine_execlists *execlists,
> return test_bit(bit, (unsigned long *)&execlists->active);
> }
>
> +void execlists_user_begin(struct intel_engine_execlists *execlists,
> + const struct execlist_port *port);
> +void execlists_user_end(struct intel_engine_execlists *execlists);
> +
> void
> execlists_cancel_port_requests(struct intel_engine_execlists * const execlists);
>
> @@ -664,7 +675,7 @@ execlists_num_ports(const struct intel_engine_execlists * const execlists)
> return execlists->port_mask + 1;
> }
>
> -static inline void
> +static inline struct execlist_port *
> execlists_port_complete(struct intel_engine_execlists * const execlists,
> struct execlist_port * const port)
> {
> @@ -675,6 +686,8 @@ execlists_port_complete(struct intel_engine_execlists * const execlists,
>
> memmove(port, port + 1, m * sizeof(struct execlist_port));
> memset(port + m, 0, sizeof(struct execlist_port));
> +
> + return port;
> }
>
> static inline unsigned int
> --
> 2.16.3
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-04-03 11:18 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-29 10:26 [PATCH] drm/i915/execlists: Track begin/end of execlists submission sequences Chris Wilson
2018-03-29 13:43 ` ✓ Fi.CI.BAT: success for " Patchwork
2018-03-29 16:39 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-03-29 17:20 ` [PATCH] " Francisco Jerez
2018-03-31 12:40 ` Chris Wilson
2018-03-31 13:06 ` [PATCH v2] " Chris Wilson
2018-04-02 16:32 ` Francisco Jerez
2018-04-03 11:33 ` Chris Wilson
2018-04-03 11:17 ` Mika Kuoppala [this message]
2018-03-31 13:34 ` ✗ Fi.CI.BAT: failure for drm/i915/execlists: Track begin/end of execlists submission sequences (rev2) Patchwork
2018-03-31 14:03 ` ✓ Fi.CI.BAT: success " Patchwork
2018-03-31 14:47 ` ✗ Fi.CI.IGT: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87po3g35ei.fsf@gaia.fi.intel.com \
--to=mika.kuoppala@linux.intel.com \
--cc=chris@chris-wilson.co.uk \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox