[Intel-gfx] [PATCH] drm/i915: Reduce number of register access during IVB+ interrupt handling

Chris Wilson chris at chris-wilson.co.uk
Mon Sep 23 15:06:09 CEST 2013


On Mon, Sep 23, 2013 at 09:57:37AM -0300, Paulo Zanoni wrote:
> 2013/9/23 Chris Wilson <chris at chris-wilson.co.uk>:
> > Register access is particularly obnoxious on Sandybridge and later due to
> > the extra work we must do around every read or write. The effect is
> > magnified on Haswell, as we have per-operation sanity checking
> > magnifying the number of reads and writes.
> >
> > Interrupt handling is supposed to be fast, yet due to the sanity checks
> > around the register accesss it is not as fast as it could be. If we look
> > closer, most of the common register operations are reading values we
> > already know, and redundant flushes. Eliminate these by storing the
> > desired values rather than reading them back during the interrupt
> > routine.
> >
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h |  4 ++--
> >  drivers/gpu/drm/i915/i915_irq.c | 22 ++++++++--------------
> >  2 files changed, 10 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index db8e4d0..f182a23 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1259,8 +1259,8 @@ typedef struct drm_i915_private {
> >         /* DPIO indirect register protection */
> >         struct mutex dpio_lock;
> >
> > -       /** Cached value of IMR to avoid reads in updating the bitfield */
> > -       u32 irq_mask;
> > +       /** Cached value of IMR/IER to avoid reads in updating the bitfield */
> > +       u32 irq_mask, irq_enable;
> >         u32 gt_irq_mask;
> >         u32 pm_irq_mask;
> >
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index d9eebca..76725c6 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -1428,7 +1428,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
> >  {
> >         struct drm_device *dev = (struct drm_device *) arg;
> >         drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
> > -       u32 de_iir, gt_iir, de_ier, sde_ier = 0;
> > +       u32 de_iir, gt_iir;
> >         irqreturn_t ret = IRQ_NONE;
> >
> >         atomic_inc(&dev_priv->irq_received);
> > @@ -1438,20 +1438,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
> >         intel_uncore_check_errors(dev);
> >
> >         /* disable master interrupt before clearing iir  */
> > -       de_ier = I915_READ(DEIER);
> > -       I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
> > -       POSTING_READ(DEIER);
> > +       I915_WRITE(DEIER, dev_priv->irq_enable & ~DE_MASTER_IRQ_CONTROL);
> >
> >         /* Disable south interrupts. We'll only write to SDEIIR once, so further
> >          * interrupts will will be stored on its back queue, and then we'll be
> >          * able to process them after we restore SDEIER (as soon as we restore
> >          * it, we'll get an interrupt if SDEIIR still has something to process
> >          * due to its back queue). */
> > -       if (!HAS_PCH_NOP(dev)) {
> > -               sde_ier = I915_READ(SDEIER);
> > +       if (!HAS_PCH_NOP(dev))
> >                 I915_WRITE(SDEIER, 0);
> > -               POSTING_READ(SDEIER);
> > -       }
> >
> >         gt_iir = I915_READ(GTIIR);
> >         if (gt_iir) {
> > @@ -1482,12 +1477,10 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
> >                 }
> >         }
> >
> > -       I915_WRITE(DEIER, de_ier);
> > +       if (!HAS_PCH_NOP(dev))
> > +               I915_WRITE(SDEIER, ~0);
> 
> Please don't change the relative order of DEIER and SDEIER. As far as
> I remember, this order is required to prevent the complete stop of
> SDEIER interrupts when we're getting too many of them (e.g.,
> underruns).

The comments refer to the ordering of DEIIR vs SDEIIR, not IER and in
particular the master-irq enable.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre



More information about the Intel-gfx mailing list