[Intel-gfx] [PATCH v2 6/8] drm/i915: sanitize rps irq enabling

Paulo Zanoni przanoni at gmail.com
Mon Nov 17 19:49:23 CET 2014


2014-11-10 11:41 GMT-02:00 Imre Deak <imre.deak at intel.com>:
> Atm we first enable the RPS interrupts then we clear any pending ones.
> By this we could lose an interrupt arriving after we unmasked it. This
> may not be a problem as the caller should handle such a race, but logic
> still calls for the opposite order. Also we can delay enabling the
> interrupts until after all the RPS initialization is ready with the
> following order:
>
> 1. clear any pending RPS interrupts
> 2. initialize RPS
> 3. enable RPS interrupts
>
> This also allows us to do the 1. and 3. step the same way for all
> platforms, so let's follow this order to simplifying things.
>
> Also make sure any queued interrupts are also cleared.
>
> v2:
> - rebase on the GEN9 patches where we don't support RPS yet, so we
>   musn't enable RPS interrupts on it (Paulo)
>
> Signed-off-by: Imre Deak <imre.deak at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c  | 11 ++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h |  1 +
>  drivers/gpu/drm/i915/intel_pm.c  | 19 +++++++++++--------
>  3 files changed, 22 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 729e9a3..89a7be1 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -255,6 +255,16 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
>         snb_update_pm_irq(dev_priv, mask, 0);
>  }
>
> +void gen6_reset_rps_interrupts(struct drm_device *dev)
> +{
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +       spin_lock_irq(&dev_priv->irq_lock);
> +       I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);
> +       I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);

What about adding POSTING_READ(gen6_pm_iir(dev_priv)) ?

(also maybe uint32_t reg = gen6_pm_iir(dev_priv))

> +       spin_unlock_irq(&dev_priv->irq_lock);
> +}
> +
>  void gen6_enable_rps_interrupts(struct drm_device *dev)
>  {
>         struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -262,7 +272,6 @@ void gen6_enable_rps_interrupts(struct drm_device *dev)
>         spin_lock_irq(&dev_priv->irq_lock);
>         WARN_ON(dev_priv->rps.pm_iir);
>         gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
> -       I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);

What about adding WARN_ON(I915_READ(gen6_pm_iir(dev_priv))) ?

>         spin_unlock_irq(&dev_priv->irq_lock);
>  }
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 2499348..fb2cf27 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -784,6 +784,7 @@ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
>  void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
>  void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
>  void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
> +void gen6_reset_rps_interrupts(struct drm_device *dev);
>  void gen6_enable_rps_interrupts(struct drm_device *dev);
>  void gen6_disable_rps_interrupts(struct drm_device *dev);
>  void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 8d164bc..f555810 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4753,8 +4753,6 @@ static void gen8_enable_rps(struct drm_device *dev)
>
>         gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8);
>
> -       gen6_enable_rps_interrupts(dev);
> -
>         gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>  }
>
> @@ -4851,8 +4849,6 @@ static void gen6_enable_rps(struct drm_device *dev)
>         dev_priv->rps.power = HIGH_POWER; /* force a reset */
>         gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
>
> -       gen6_enable_rps_interrupts(dev);
> -
>         rc6vids = 0;
>         ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
>         if (IS_GEN6(dev) && ret) {
> @@ -5344,8 +5340,6 @@ static void cherryview_enable_rps(struct drm_device *dev)
>
>         valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
>
> -       gen6_enable_rps_interrupts(dev);
> -
>         gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>  }
>
> @@ -5424,8 +5418,6 @@ static void valleyview_enable_rps(struct drm_device *dev)
>
>         valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
>
> -       gen6_enable_rps_interrupts(dev);
> -
>         gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>  }
>
> @@ -6239,6 +6231,13 @@ static void intel_gen6_powersave_work(struct work_struct *work)
>
>         mutex_lock(&dev_priv->rps.hw_lock);
>
> +       /*
> +        * TODO: reset/enable RPS interrupts on GEN9 too, once RPS support is
> +        * added for it.
> +        */
> +       if (INTEL_INFO(dev)->gen != 9)
> +               gen6_reset_rps_interrupts(dev);

I see that in this series you're using "gen != 9" checks, but I'd
change them to "gen < 9", just in case...

> +
>         if (IS_CHERRYVIEW(dev)) {
>                 cherryview_enable_rps(dev);
>         } else if (IS_VALLEYVIEW(dev)) {
> @@ -6253,6 +6252,10 @@ static void intel_gen6_powersave_work(struct work_struct *work)
>                 __gen6_update_ring_freq(dev);
>         }
>         dev_priv->rps.enabled = true;
> +
> +       if (INTEL_INFO(dev)->gen != 9)
> +               gen6_enable_rps_interrupts(dev);
> +
>         mutex_unlock(&dev_priv->rps.hw_lock);
>
>         intel_runtime_pm_put(dev_priv);
> --
> 1.8.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni



More information about the Intel-gfx mailing list