[Intel-gfx] [PATCH v3] drm/i915/execlists: Move WA_TAIL_DWORDS to callee

Rodrigo Vivi rodrigo.vivi at gmail.com
Fri Feb 5 22:56:51 UTC 2016


On Fri, Feb 5, 2016 at 11:31 AM, Dave Gordon <david.s.gordon at intel.com> wrote:
> From: Chris Wilson <chris at chris-wilson.co.uk>
>
> Currently emit-request starts writing to the ring and reserves space
> for a workaround to be emitted later whilst submitting the request. It
> is easier to read if the caller only allocates sufficient space for
> its access (then the reader can quickly verify that the ring begin
> allocates the exact space for the number of dwords emitted) and closes
> the access to the ring. During submit, if we need to add the workaround,
> we can reacquire ring access, in the assurance that we reserved space
> for ourselves when beginning the request.
>
> v3:
>     Reinstated #define for WA_TAIL_DWORDS so we could accommodate GPUs
>     that required different amounts of padding, generalised NOOP fill
>     [Rodrigo Vivi], added W/A space to reserved amount and updated
>     code comments [Dave Gordon],
>
> Originally-by: Rodrigo Vivi <rodrigo.vivi at gmail.com>
> Rewritten-by: Chris Wilson <chris at chris-wilson.co.uk>
> Further-tweaked-by: Dave Gordon <david.s.gordon at intel.com>
>
> Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi at gmail.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Dave Gordon <david.s.gordon at intel.com>
> Cc: Ben Widawsky <benjamin.widawsky at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_lrc.c | 80 ++++++++++++++++++++++++----------------
>  1 file changed, 49 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 3a03646..8b278f1 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -225,6 +225,13 @@ enum {
>  #define GEN8_CTX_ID_SHIFT 32
>  #define CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT  0x17
>
> +/*
> + * Reserve space for 2 NOOPs at the end of each request,
> + * to be used as a workaround for not being allowed to
> + * do lite restore with HEAD==TAIL (WaIdleLiteRestore).
> + */
> +#define WA_TAIL_DWORDS 2

This patch really organize things better, but I still don't like the
WA_TAIL_DWORDS hardcoded here instead in a place where I can switch
for different platofms.

> +
>  static int intel_lr_context_pin(struct intel_context *ctx,
>                                 struct intel_engine_cs *engine);
>  static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
> @@ -462,10 +469,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
>                  */
>                 if (req0->elsp_submitted) {
>                         /*
> -                        * Apply the wa NOOPS to prevent ring:HEAD == req:TAIL
> -                        * as we resubmit the request. See gen8_emit_request()
> -                        * for where we prepare the padding after the end of the
> -                        * request.
> +                        * Consume the W/A NOOPs to prevent ring:HEAD == req:TAIL as
> +                        * we resubmit the request. See intel_logical_ring_submit()
> +                        * where we prepare the padding after the end of the request.
>                          */
>                         struct intel_ringbuffer *ringbuf;
>
> @@ -752,33 +758,47 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req,
>  }
>
>  /*
> - * intel_logical_ring_advance_and_submit() - advance the tail and submit the workload
> - * @request: Request to advance the logical ringbuffer of.
> + * intel_logical_ring_submit() - submit the workload (to GuC or execlist queue)
> + * @request: Request to submit
>   *
> - * The tail is updated in our logical ringbuffer struct, not in the actual context. What
> - * really happens during submission is that the context and current tail will be placed
> - * on a queue waiting for the ELSP to be ready to accept a new context submission. At that
> - * point, the tail *inside* the context is updated and the ELSP written to.
> + * The tail is updated in our logical ringbuffer struct, not in the actual
> + * context. What really happens during submission is that the context and
> + * current tail will be placed on a queue waiting for the ELSP to be ready
> + * to accept a new context submission. At that point, the tail *inside* the
> + * context is updated and the ELSP written to by the submitting agent i.e.
> + * either the driver (in execlist mode), or the GuC (in GuC-submission mode).
>   */
>  static int
> -intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
> +intel_logical_ring_submit(struct drm_i915_gem_request *request)
>  {
>         struct intel_ringbuffer *ringbuf = request->ringbuf;
>         struct drm_i915_private *dev_priv = request->i915;
>         struct intel_engine_cs *engine = request->ring;
>
> -       intel_logical_ring_advance(ringbuf);
>         request->tail = ringbuf->tail;
>
>         /*
> -        * Here we add two extra NOOPs as padding to avoid
> -        * lite restore of a context with HEAD==TAIL.
> -        *
> -        * Caller must reserve WA_TAIL_DWORDS for us!
> +        * Fill in a few NOOPs after the end of the request proper,
> +        * as a buffer between requests to be used as a workaround
> +        * for not being allowed to do lite restore with HEAD==TAIL.
> +        * (WaIdleLiteRestore). These words may be consumed by the
> +        * submission mechanism if a context is *re*submitted while
> +        * (apparently) still active; otherwise, they will be left
> +        * as a harmless preamble to the next request.
>          */
> -       intel_logical_ring_emit(ringbuf, MI_NOOP);
> -       intel_logical_ring_emit(ringbuf, MI_NOOP);
> -       intel_logical_ring_advance(ringbuf);
> +       if (WA_TAIL_DWORDS > 0) {
> +               int ret, i;
> +
> +               /* Safe because we reserved the space earlier */
> +               ret = intel_logical_ring_begin(request, WA_TAIL_DWORDS);
> +               if (WARN_ON(ret != 0))
> +                       return ret;
> +
> +               for (i = 0; i < WA_TAIL_DWORDS; ++i)
> +                       intel_logical_ring_emit(ringbuf, MI_NOOP);
> +
> +               intel_logical_ring_advance(ringbuf);
> +       }
>
>         if (intel_ring_stopped(engine))
>                 return 0;
> @@ -907,7 +927,8 @@ int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request)
>          * adding any commands to it then there might not actually be
>          * sufficient room for the submission commands.
>          */
> -       intel_ring_reserved_space_reserve(request->ringbuf, MIN_SPACE_FOR_ADD_REQUEST);
> +       intel_ring_reserved_space_reserve(request->ringbuf,
> +                       MIN_SPACE_FOR_ADD_REQUEST + WA_TAIL_DWORDS);
>
>         return intel_logical_ring_begin(request, 0);
>  }
> @@ -1875,13 +1896,6 @@ static void bxt_a_set_seqno(struct intel_engine_cs *ring, u32 seqno)
>         intel_flush_status_page(ring, I915_GEM_HWS_INDEX);
>  }
>
> -/*
> - * Reserve space for 2 NOOPs at the end of each request to be
> - * used as a workaround for not being allowed to do lite
> - * restore with HEAD==TAIL (WaIdleLiteRestore).
> - */
> -#define WA_TAIL_DWORDS 2
> -
>  static inline u32 hws_seqno_address(struct intel_engine_cs *engine)
>  {
>         return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR;
> @@ -1892,7 +1906,7 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
>         struct intel_ringbuffer *ringbuf = request->ringbuf;
>         int ret;
>
> -       ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS);
> +       ret = intel_logical_ring_begin(request, 6);
>         if (ret)
>                 return ret;
>
> @@ -1908,7 +1922,9 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
>         intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
>         intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
>         intel_logical_ring_emit(ringbuf, MI_NOOP);
> -       return intel_logical_ring_advance_and_submit(request);
> +       intel_logical_ring_advance(ringbuf);
> +
> +       return intel_logical_ring_submit(request);
>  }
>
>  static int gen8_emit_request_render(struct drm_i915_gem_request *request)
> @@ -1916,7 +1932,7 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>         struct intel_ringbuffer *ringbuf = request->ringbuf;
>         int ret;
>
> -       ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS);
> +       ret = intel_logical_ring_begin(request, 6);
>         if (ret)
>                 return ret;
>
> @@ -1933,7 +1949,9 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>         intel_logical_ring_emit(ringbuf, 0);
>         intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request));
>         intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
> -       return intel_logical_ring_advance_and_submit(request);
> +       intel_logical_ring_advance(ringbuf);
> +
> +       return intel_logical_ring_submit(request);
>  }
>
>  static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req)
> --
> 1.9.1
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br


More information about the Intel-gfx mailing list