[Intel-gfx] [PATCH 10/10] drm/i915/icl: Only ack irq identities we did handle

Daniele Ceraolo Spurio daniele.ceraolospurio at intel.com
Thu Sep 20 17:14:13 UTC 2018



On 20/09/18 07:33, Mika Kuoppala wrote:
> If we ack the identities immediately after they have been
> handled, it should unblock next interrupt accumulation
> in the gathering register earlier. It also allows us to
> remove time based polling of valid bit. If we don't get a valid
> sample now, we will likely get a valid sample on next interrupt,
> which will be generated due to skipping the ack. The downside
> is that we will have as many ack writes as there were identities
> handled.
> 

I'm not sure this is going to work. It looks like if we skip the 
clearing of the identity register we need to skip the clearing of 
INTR_DW as well because the HW doesn't seem to set that again. If we 
clear it, when the interrupt gets re-triggered the driver won't be able 
to handle it and so it'll keep being re-triggered in a loop. I've just 
confirmed this behavior on the current code (i.e. without this series 
applied) by simply pretending the ident was not valid for the first 
interrupt:

[  728.765749] [drm:gen11_gt_engine_identity [i915]] *ERROR* 
INTR_IDENTITY_REG0:15 0x00000000 not valid!
[  728.765800] [drm:gen11_irq_handler [i915]] *ERROR* GT_INTR_DW0 blank!
[  728.765865] [drm:gen11_irq_handler [i915]] *ERROR* GT_INTR_DW0 blank!
[  728.766050] [drm:gen11_irq_handler [i915]] *ERROR* GT_INTR_DW0 blank!
[... more of the same ...]
[  782.395257] [drm:gen11_irq_handler [i915]] *ERROR* GT_INTR_DW0 blank!
[  782.395293] [drm:gen11_irq_handler [i915]] *ERROR* GT_INTR_DW0 blank!

I haven't checked in detail all the other patches in the series yet so 
not sure if any of them can mitigate this issue.

Daniele

> Leave small retry loop for safety and with debugs to see if we
> ever encounter read with valid not set.
> 
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> ---
>   drivers/gpu/drm/i915/i915_irq.c | 26 +++++++++++---------------
>   1 file changed, 11 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 27116e3f21af..beb9fe4abf1f 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2965,22 +2965,18 @@ gen11_gt_engine_identity(struct drm_i915_private * const i915,
>   			 const unsigned int bank, const unsigned int bit)
>   {
>   	void __iomem * const regs = i915->regs;
> -	u32 timeout_ts;
> -	u32 ident;
> +	u32 ident, retry = 0;
>   
>   	lockdep_assert_held(&i915->irq_lock);
>   
>   	raw_reg_write(regs, GEN11_IIR_REG_SELECTOR(bank), BIT(bit));
>   
> -	/*
> -	 * NB: Specs do not specify how long to spin wait,
> -	 * so we do ~100us as an educated guess.
> -	 */
> -	timeout_ts = (local_clock() >> 10) + 100;
>   	do {
>   		ident = raw_reg_read(regs, GEN11_INTR_IDENTITY_REG(bank));
> -	} while (!(ident & GEN11_INTR_DATA_VALID) &&
> -		 !time_after32(local_clock() >> 10, timeout_ts));
> +	} while (!(ident & GEN11_INTR_DATA_VALID) && ++retry <= 10);
> +
> +	if (unlikely(GEM_SHOW_DEBUG() && retry))
> +		WARN_ONCE(1, "INTR_IDENTITY took %u reads to settle\n", retry);
>   
>   	if (unlikely(!(ident & GEN11_INTR_DATA_VALID))) {
>   		DRM_ERROR("INTR_IDENTITY_REG%u:%u 0x%08x not valid!\n",
> @@ -3031,9 +3027,6 @@ gen11_gt_identity_handler(struct drm_i915_private * const i915,
>   	const u8 instance = GEN11_INTR_ENGINE_INSTANCE(identity);
>   	const u16 intr = GEN11_INTR_ENGINE_INTR(identity);
>   
> -	if (unlikely(!intr))
> -		return;
> -
>   	if (class <= COPY_ENGINE_CLASS)
>   		return gen11_engine_irq_handler(i915, class, instance, intr);
>   
> @@ -3065,11 +3058,14 @@ gen11_gt_bank_handler(struct drm_i915_private * const i915,
>   		const u32 ident = gen11_gt_engine_identity(i915,
>   							   bank, bit);
>   
> +		if (unlikely(!ident))
> +			continue;
> +
>   		gen11_gt_identity_handler(i915, ident);
> -	}
>   
> -	/* Clear must be after shared has been served for engine */
> -	raw_reg_write(regs, GEN11_GT_INTR_DW(bank), intr_dw);
> +		/* Clear must be after shared has been served for engine */
> +		raw_reg_write(regs, GEN11_GT_INTR_DW(bank), BIT(bit));
> +	}
>   }
>   
>   static void
> 


More information about the Intel-gfx mailing list