From: Daniel Vetter <daniel@ffwll.ch>
To: Paulo Zanoni <przanoni@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>,
Intel Graphics Development <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH] drm/i915: fix locking around ironlake_enable|disable_display_irq
Date: Thu, 27 Jun 2013 12:37:06 +0200 [thread overview]
Message-ID: <20130627103706.GM18285@phenom.ffwll.local> (raw)
In-Reply-To: <CA+gsUGTi_noNg9h1Vb+enYEsJU3HfWUs=BS8ebN5e_k3YrKNJw@mail.gmail.com>
On Wed, Jun 26, 2013 at 06:15:42PM -0300, Paulo Zanoni wrote:
> 2013/6/25 Daniel Vetter <daniel.vetter@ffwll.ch>:
> > The haswell unclaimed register handling code forgot to take the
> > spinlock. Since this is in the context of the non-rentrant interupt
> > handler and we only have one interrupt handler it is sufficient to
> > just grab the spinlock - we do not need to exclude any other
> > interrupts from running on the same cpu.
> >
> > To prevent such gaffles in the future sprinkle assert_spin_locked over
> > these functions. Unfornately this requires us to hold the spinlock in
> > the ironlake postinstall hook where it is not strictly required:
> > Currently that is run in single-threaded context and with userspace
> > exlcuded from running concurrent ioctls. Add a comment explaining
> > this.
> >
> > v2: ivb_can_enable_err_int also needs to be protected by the spinlock.
> > To ensure this won't happen in the future again also sprinkle a
> > spinlock assert in there.
>
> Why does ivb_can_enable_err_int need it? Maybe we should add a comment
> inside the function explaining why it needs it.
It does access ->cpu_fifo_underrun_disabled. Just reading that won't race,
but it's important that the subsequent state change is consistent with the
state we've read (i.e. no one must be able to sneak in). Hence we need to
hold the lock around the entire if (can_enable) do_enable; sequence.
>
>
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> > drivers/gpu/drm/i915/i915_irq.c | 27 ++++++++++++++++++++++++---
> > 1 file changed, 24 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index c482e8a..ff1fed4 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -95,6 +95,8 @@ static void i915_hpd_irq_setup(struct drm_device *dev);
> > static void
> > ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
> > {
> > + assert_spin_locked(&dev_priv->irq_lock);
> > +
> > if ((dev_priv->irq_mask & mask) != 0) {
> > dev_priv->irq_mask &= ~mask;
> > I915_WRITE(DEIMR, dev_priv->irq_mask);
> > @@ -105,6 +107,8 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
> > static void
> > ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
> > {
> > + assert_spin_locked(&dev_priv->irq_lock);
> > +
> > if ((dev_priv->irq_mask & mask) != mask) {
> > dev_priv->irq_mask |= mask;
> > I915_WRITE(DEIMR, dev_priv->irq_mask);
> > @@ -118,6 +122,8 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
> > struct intel_crtc *crtc;
> > enum pipe pipe;
> >
> > + assert_spin_locked(&dev_priv->irq_lock);
> > +
> > for_each_pipe(pipe) {
> > crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
> >
> > @@ -1218,8 +1224,11 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
> > /* On Haswell, also mask ERR_INT because we don't want to risk
> > * generating "unclaimed register" interrupts from inside the interrupt
> > * handler. */
> > - if (IS_HASWELL(dev))
> > + if (IS_HASWELL(dev)) {
> > + spin_lock(&dev_priv->irq_lock);
> > ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
> > + spin_unlock(&dev_priv->irq_lock);
> > + }
> >
> > gt_iir = I915_READ(GTIIR);
> > if (gt_iir) {
> > @@ -1272,8 +1281,12 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
> > ret = IRQ_HANDLED;
> > }
> >
> > - if (IS_HASWELL(dev) && ivb_can_enable_err_int(dev))
> > - ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
> > + if (IS_HASWELL(dev) && ivb_can_enable_err_int(dev)) {
> > + spin_lock(&dev_priv->irq_lock);
> > + if (ivb_can_enable_err_int(dev))
>
> You're calling ivb_can_enable_err_int twice here.
Oops, will fix.
>
>
> > + ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
> > + spin_unlock(&dev_priv->irq_lock);
> > + }
> >
> > I915_WRITE(DEIER, de_ier);
> > POSTING_READ(DEIER);
> > @@ -2633,6 +2646,8 @@ static void ibx_irq_postinstall(struct drm_device *dev)
> >
> > static int ironlake_irq_postinstall(struct drm_device *dev)
> > {
> > + unsigned long irqflags;
> > +
> > drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
> > /* enable kind of interrupts always enabled */
> > u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
> > @@ -2671,7 +2686,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
> > /* Clear & enable PCU event interrupts */
> > I915_WRITE(DEIIR, DE_PCU_EVENT);
> > I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT);
> > +
> > + /* spinlocking not required here for correctness since interrupt
> > + * setup is guaranteed to run in single-threaded context. But we
> > + * need it to make the assert_spin_locked happy. */
> > + spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
>
> If spinlocking is not even required, why take the irqsave one instead
> of just spin_lock()?
lockdep will complain about the inconsistent locking usage, since just
doing a spin_lock while the interrupt handler could also do a spin_lock
call can deadlock. Ofc lockdep doesn't now that at this point our
interrupt handler can't run, but it's imo established procedure to not
care about such details. So imo this doesn't warrant an extended comment.
>
>
> > ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT);
> > + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
> > }
> >
> > return 0;
> > --
> > 1.8.1.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>
>
> --
> Paulo Zanoni
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
next prev parent reply other threads:[~2013-06-27 10:37 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-12 11:37 [PATCH 00/24] irq locking review Daniel Vetter
2013-06-12 11:37 ` [PATCH 01/24] drm/i915: fix locking around ironlake_enable|disable_display_irq Daniel Vetter
2013-06-25 12:26 ` [PATCH] " Daniel Vetter
2013-06-26 21:15 ` Paulo Zanoni
2013-06-27 10:37 ` Daniel Vetter [this message]
2013-06-12 11:37 ` [PATCH 02/24] drm/i915: close tiny race in the ilk pcu even interrupt setup Daniel Vetter
2013-06-26 21:20 ` Paulo Zanoni
2013-06-12 11:37 ` [PATCH 03/24] drm/i915: assert_spin_locked for pipestat interrupt enable/disable Daniel Vetter
2013-06-26 21:44 ` Paulo Zanoni
2013-06-12 11:37 ` [PATCH 04/24] drm/i915: s/hotplug_irq_storm_detect/intel_hpd_irq_handler/ Daniel Vetter
2013-06-12 14:22 ` Egbert Eich
2013-06-12 11:37 ` [PATCH 05/24] drm/i915: fold the hpd_irq_setup call into intel_hpd_irq_handler Daniel Vetter
[not found] ` <20920.34096.704203.67316@linux-qknr.site>
2013-06-12 15:00 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 06/24] drm/i915: fold the queue_work " Daniel Vetter
2013-06-12 14:29 ` Egbert Eich
2013-06-12 11:37 ` [PATCH 07/24] drm/i915: fold the no-irq check " Daniel Vetter
2013-06-12 14:33 ` Egbert Eich
2013-06-26 22:35 ` Paulo Zanoni
2013-06-27 10:39 ` Daniel Vetter
2013-06-27 11:44 ` [PATCH 1/8] drm/i915: fix locking around ironlake_enable|disable_display_irq Daniel Vetter
2013-06-27 11:44 ` [PATCH 2/8] drm/i915: close tiny race in the ilk pcu even interrupt setup Daniel Vetter
2013-06-27 11:45 ` [PATCH 3/8] drm/i915: assert_spin_locked for pipestat interrupt enable/disable Daniel Vetter
2013-06-27 11:45 ` [PATCH 4/8] drm/i915: s/hotplug_irq_storm_detect/intel_hpd_irq_handler/ Daniel Vetter
2013-06-27 11:45 ` [PATCH 5/8] drm/i915: fold the hpd_irq_setup call into intel_hpd_irq_handler Daniel Vetter
2013-06-27 11:45 ` [PATCH 6/8] drm/i915: fold the queue_work " Daniel Vetter
2013-06-27 12:13 ` Chris Wilson
2013-06-27 11:45 ` [PATCH 7/8] drm/i915: fold the no-irq check " Daniel Vetter
2013-06-27 12:14 ` Chris Wilson
2013-06-27 11:45 ` [PATCH 8/8] drm/i915: fix hpd interrupt register locking Daniel Vetter
2013-06-27 14:41 ` Paulo Zanoni
2013-06-27 15:52 ` [PATCH 1/6] drm/i915: assert_spin_locked for pipestat interrupt enable/disable Daniel Vetter
2013-06-27 15:52 ` [PATCH 2/6] drm/i915: s/hotplug_irq_storm_detect/intel_hpd_irq_handler/ Daniel Vetter
2013-06-27 15:52 ` [PATCH 3/6] drm/i915: fold the hpd_irq_setup call into intel_hpd_irq_handler Daniel Vetter
2013-06-27 15:52 ` [PATCH 4/6] drm/i915: fold the queue_work " Daniel Vetter
2013-06-27 15:52 ` [PATCH 5/6] drm/i915: fold the no-irq check " Daniel Vetter
2013-06-27 15:52 ` [PATCH 6/6] drm/i915: fix hpd interrupt register locking Daniel Vetter
2013-07-04 19:22 ` [PATCH 1/6] drm/i915: assert_spin_locked for pipestat interrupt enable/disable Daniel Vetter
2013-06-27 17:44 ` [PATCH 8/8] drm/i915: fix hpd interrupt register locking Daniel Vetter
2013-06-12 11:37 ` [PATCH 08/24] " Daniel Vetter
2013-06-12 14:59 ` Egbert Eich
2013-06-12 15:10 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 09/24] drm/i915: extract ibx_display_interrupt_update Daniel Vetter
2013-06-25 12:27 ` [PATCH] " Daniel Vetter
2013-06-12 11:37 ` [PATCH 10/24] drm/i915: remove SERR_INT clearing in the postinstall hook Daniel Vetter
2013-06-27 19:34 ` Paulo Zanoni
2013-07-04 19:49 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 11/24] drm/i915: improve SERR_INT clearing for fifo underrun reporting Daniel Vetter
2013-06-27 20:19 ` Paulo Zanoni
2013-07-04 19:55 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 12/24] drm/i915: improve GEN7_ERR_INT " Daniel Vetter
2013-06-12 11:37 ` [PATCH 13/24] drm/i915: kill lpt pch transcoder->crtc mapping code for fifo underruns Daniel Vetter
2013-06-12 13:04 ` Paulo Zanoni
2013-06-12 14:46 ` [PATCH] " Daniel Vetter
2013-06-27 20:45 ` Paulo Zanoni
2013-07-04 20:41 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 14/24] drm/i915: irq handlers don't need interrupt-safe spinlocks Daniel Vetter
2013-06-25 12:27 ` [PATCH] " Daniel Vetter
2013-06-27 21:14 ` Paulo Zanoni
2013-06-27 22:40 ` Daniel Vetter
2013-06-28 16:57 ` Paulo Zanoni
2013-06-12 11:37 ` [PATCH 15/24] drm/i915: streamline hsw_pm_irq_handler Daniel Vetter
2013-06-25 12:28 ` [PATCH] " Daniel Vetter
2013-06-12 11:37 ` [PATCH 16/24] drm/i915: queue work outside spinlock in hsw_pm_irq_handler Daniel Vetter
2013-06-12 11:37 ` [PATCH 17/24] drm/i915: kill dev_priv->rps.lock Daniel Vetter
2013-06-28 3:35 ` Ben Widawsky
2013-06-28 3:35 ` Ben Widawsky
2013-06-12 11:37 ` [PATCH 18/24] drm/i915: unify ring irq refcounts (again) Daniel Vetter
2013-06-28 17:24 ` Ben Widawsky
2013-07-04 20:52 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 19/24] drm/i915: don't enable PM_VEBOX_CS_ERROR_INTERRUPT Daniel Vetter
2013-06-12 17:13 ` Ben Widawsky
2013-06-12 17:18 ` Daniel Vetter
2013-06-12 18:19 ` Ben Widawsky
2013-06-12 18:32 ` Daniel Vetter
2013-06-12 18:51 ` Ben Widawsky
2013-06-28 17:25 ` Ben Widawsky
2013-06-12 11:37 ` [PATCH 20/24] drm/i915: kill bogus GTIIR clearing in vlv_preinstall hook Daniel Vetter
2013-06-28 17:01 ` Ben Widawsky
2013-07-04 20:56 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 21/24] drm/i915: unify PM interrupt preinstall sequence Daniel Vetter
2013-06-28 17:26 ` Ben Widawsky
2013-07-04 21:03 ` Daniel Vetter
2013-06-12 11:37 ` [PATCH 22/24] drm/i915: unify GT/PM irq postinstall code Daniel Vetter
2013-06-12 11:37 ` [PATCH 23/24] drm/i915: extract rps interrupt enable/disable helpers Daniel Vetter
2013-06-12 11:37 ` [PATCH 24/24] drm/i915: simplify rps interrupt enabling/disabling sequence Daniel Vetter
2013-06-12 22:32 ` Ben Widawsky
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=20130627103706.GM18285@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=daniel.vetter@ffwll.ch \
--cc=intel-gfx@lists.freedesktop.org \
--cc=przanoni@gmail.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