From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: Michel Thierry <michel.thierry@intel.com>,
intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v3] drm/i915: Consider HW CSB write pointer before resetting the sw read pointer
Date: Mon, 28 Sep 2015 17:00:12 +0300 [thread overview]
Message-ID: <878u7qabkj.fsf@gaia.fi.intel.com> (raw)
In-Reply-To: <1443446247-13837-1-git-send-email-michel.thierry@intel.com>
Michel Thierry <michel.thierry@intel.com> writes:
> A previous commit resets the Context Status Buffer (CSB) read pointer in
> ring init
> commit c0a03a2e4c4e ("drm/i915: Reset CSB read pointer in ring init")
>
> This is generally correct, but this pointer is not reset after
> suspend/resume in some platforms (cht). In this case, the driver should
> read the register value instead of resetting the sw read counter to 0.
> Otherwise we process old events, leading to unwanted pre-emptions or
> something worse.
>
> But in other platforms (bdw) and also during GPU reset or power up, the
> CSBWP is reset to 0x7 (an invalid number), and in this case the read
> pointer should be set to 5 (the interrupt code will increment this
> counter one more time, and will start reading from CSB[0]).
>
> v2: When the CSB registers are reset, the read pointer needs to be set
> to 5, otherwise the first write (CSB[0]) won't be read (Mika).
> Replace magic numbers with GEN8_CSB_ENTRIES (6) and GEN8_CSB_PTR_MASK
> (0x07).
> v3: Rebased on top of "Parametrize LRC registers" patch.
>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Signed-off-by: Lei Shen <lei.shen@intel.com>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> Signed-off-by: Michel Thierry <michel.thierry@intel.com>
> ---
> drivers/gpu/drm/i915/intel_lrc.c | 39 ++++++++++++++++++++++++++++++++-------
> drivers/gpu/drm/i915/intel_lrc.h | 2 ++
> 2 files changed, 34 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 256167b..825fa7a 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -511,16 +511,16 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring)
> status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
>
> read_pointer = ring->next_context_status_buffer;
> - write_pointer = status_pointer & 0x07;
> + write_pointer = status_pointer & GEN8_CSB_PTR_MASK;
> if (read_pointer > write_pointer)
> - write_pointer += 6;
> + write_pointer += GEN8_CSB_ENTRIES;
>
> spin_lock(&ring->execlist_lock);
>
> while (read_pointer < write_pointer) {
> read_pointer++;
> - status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer % 6));
> - status_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, read_pointer % 6));
> + status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer % GEN8_CSB_ENTRIES));
> + status_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, read_pointer % GEN8_CSB_ENTRIES));
>
> if (status & GEN8_CTX_STATUS_IDLE_ACTIVE)
> continue;
> @@ -552,10 +552,12 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring)
> spin_unlock(&ring->execlist_lock);
>
> WARN(submit_contexts > 2, "More than two context complete events?\n");
> - ring->next_context_status_buffer = write_pointer % 6;
> + ring->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES;
>
> I915_WRITE(RING_CONTEXT_STATUS_PTR(ring),
> - _MASKED_FIELD(0x07 << 8, ((u32)ring->next_context_status_buffer & 0x07) << 8));
> + _MASKED_FIELD(GEN8_CSB_PTR_MASK << 8,
> + ((u32)ring->next_context_status_buffer &
> + GEN8_CSB_PTR_MASK) << 8));
> }
>
> static int execlists_context_queue(struct drm_i915_gem_request *request)
> @@ -1477,6 +1479,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring)
> {
> struct drm_device *dev = ring->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + u8 next_context_status_buffer_hw;
>
> lrc_setup_hardware_status_page(ring,
> ring->default_context->engine[ring->id].state);
> @@ -1494,7 +1497,29 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring)
> _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) |
> _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
> POSTING_READ(RING_MODE_GEN7(ring));
> - ring->next_context_status_buffer = 0;
> +
> + /*
> + * Instead of resetting the Context Status Buffer (CSB) read pointer to
> + * zero, we need to read the write pointer from hardware and use its
> + * value because "this register is power context save restored".
> + * Effectively, these states have been observed:
> + *
> + * | Suspend-to-idle (freeze) | Suspend-to-RAM (mem) |
> + * BDW | CSB regs not reset | CSB regs reset |
> + * CHT | CSB regs not reset | CSB regs not reset |
> + */
SKL acts similar to BDW.
> + next_context_status_buffer_hw = (I915_READ(RING_CONTEXT_STATUS_PTR(ring))
> + & GEN8_CSB_PTR_MASK);
> +
> + /*
> + * When the CSB registers are reset (also after power-up / gpu reset),
> + * CSB write pointer is set to all 1's, which is not valid, use '5' in
> + * this special case, so the first element read is CSB[0].
> + */
> + if (next_context_status_buffer_hw == GEN8_CSB_PTR_MASK)
> + next_context_status_buffer_hw = (GEN8_CSB_ENTRIES - 1);
> +
Now that this has been unravelled, I hope we can move towards
of removing the driver state of next context buffer completely:
http://lists.freedesktop.org/archives/intel-gfx/2015-May/067313.html
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
> + ring->next_context_status_buffer = next_context_status_buffer_hw;
> DRM_DEBUG_DRIVER("Execlists enabled for %s\n", ring->name);
>
> memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
> diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
> index 8a08a27..4e60d54 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.h
> +++ b/drivers/gpu/drm/i915/intel_lrc.h
> @@ -25,6 +25,8 @@
> #define _INTEL_LRC_H_
>
> #define GEN8_LR_CONTEXT_ALIGN 4096
> +#define GEN8_CSB_ENTRIES 6
> +#define GEN8_CSB_PTR_MASK 0x07
>
> /* Execlists regs */
> #define RING_ELSP(ring) ((ring)->mmio_base+0x230)
> --
> 2.5.3
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2015-09-28 14:00 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-23 14:43 [PATCH] drm/i915: Consider HW CSB write pointer before resetting the sw read pointer Michel Thierry
2015-09-25 15:44 ` Mika Kuoppala
2015-09-25 17:33 ` Michel Thierry
2015-09-28 12:25 ` [PATCH v2] " Michel Thierry
2015-09-28 13:17 ` [PATCH v3] " Michel Thierry
2015-09-28 14:00 ` Mika Kuoppala [this message]
2015-09-28 14:12 ` Daniel Vetter
2015-09-28 14:30 ` Jani Nikula
2015-09-28 13:49 ` [PATCH v2] " Michel Thierry
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=878u7qabkj.fsf@gaia.fi.intel.com \
--to=mika.kuoppala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=michel.thierry@intel.com \
/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