* [PATCH 0/3] drm/i915: A few more vblank interrupt fixes
@ 2014-05-20 14:20 ville.syrjala
2014-05-20 14:20 ` [PATCH 1/3] drm: Always reject drm_vblank_get() after drm_vblank_off() ville.syrjala
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: ville.syrjala @ 2014-05-20 14:20 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
We have a few more corner cases with the drm_vblank_on/off stuff. This
series aims to fix those.
I couldn't think of a good way to write a test case for the drm_vblank_get()
issue since it's a transient state that occurs briefly during modeset. So
I added asserts for it instead.
So far I didn't write a test for the intel_sanitize_crtc() case either. But
I can try to think of something for that...
Ville Syrjälä (3):
drm: Always reject drm_vblank_get() after drm_vblank_off()
drm/i915: Warn if drm_vblank_get() still works after drm_vblank_off()
drm/i915: Re-enable vblank irqs for already active pipes
drivers/gpu/drm/drm_irq.c | 14 ++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++++++++++
2 files changed, 35 insertions(+)
--
1.8.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] drm: Always reject drm_vblank_get() after drm_vblank_off()
2014-05-20 14:20 [PATCH 0/3] drm/i915: A few more vblank interrupt fixes ville.syrjala
@ 2014-05-20 14:20 ` ville.syrjala
2014-05-20 14:20 ` [PATCH 2/3] drm/i915: Warn if drm_vblank_get() still works " ville.syrjala
2014-05-20 14:20 ` [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes ville.syrjala
2 siblings, 0 replies; 6+ messages in thread
From: ville.syrjala @ 2014-05-20 14:20 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Make sure drm_vblank_get() never succeeds when called between
drm_vblank_off() and drm_vblank_on(). Borrow a trick from the
old drm_vblank_{pre,post}_modeset() functions and just bump
the refcount in drm_vblank_off() and drop it in drm_vblank_on().
Hopefully the use of inmodeset won't conflict badly with
drm_vblank_{pre,post}_modeset().
For i915 there's a window between drm_vblank_off() and marking the
crtc as inactive where the current code still allows drm_vblank_get().
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/drm_irq.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index dd786d8..69a2b2a 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -958,6 +958,15 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
}
spin_unlock(&dev->event_lock);
+ /*
+ * Prevent subsequent drm_vblank_get() from re-enabling
+ * the vblank interrupt by bumping the refcount.
+ */
+ if (!dev->vblank[crtc].inmodeset) {
+ atomic_inc(&dev->vblank[crtc].refcount);
+ dev->vblank[crtc].inmodeset = 1;
+ }
+
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
EXPORT_SYMBOL(drm_vblank_off);
@@ -972,6 +981,11 @@ void drm_vblank_on(struct drm_device *dev, int crtc)
unsigned long irqflags;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ /* Drop our private "prevent drm_vblank_get" refcount */
+ if (dev->vblank[crtc].inmodeset) {
+ atomic_dec(&dev->vblank[crtc].refcount);
+ dev->vblank[crtc].inmodeset = 0;
+ }
/* re-enable interrupts if there's are users left */
if (atomic_read(&dev->vblank[crtc].refcount) != 0)
WARN_ON(drm_vblank_enable(dev, crtc));
--
1.8.5.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] drm/i915: Warn if drm_vblank_get() still works after drm_vblank_off()
2014-05-20 14:20 [PATCH 0/3] drm/i915: A few more vblank interrupt fixes ville.syrjala
2014-05-20 14:20 ` [PATCH 1/3] drm: Always reject drm_vblank_get() after drm_vblank_off() ville.syrjala
@ 2014-05-20 14:20 ` ville.syrjala
2014-05-20 14:20 ` [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes ville.syrjala
2 siblings, 0 replies; 6+ messages in thread
From: ville.syrjala @ 2014-05-20 14:20 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index df58afc..9420f4f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1298,6 +1298,17 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
}
}
+static void assert_vblank_disabled(struct intel_crtc *crtc)
+{
+ struct drm_device *dev = crtc->base.dev;
+ enum pipe pipe = crtc->pipe;
+
+ if (WARN_ON(drm_vblank_get(dev, pipe) == 0)) {
+ drm_vblank_put(dev, pipe);
+ drm_vblank_off(dev, pipe);
+ }
+}
+
static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
{
u32 val;
@@ -3863,6 +3874,8 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
+ assert_vblank_disabled(intel_crtc);
+
intel_enable_primary_hw_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
/* The fixup needs to happen before cursor is enabled */
@@ -3899,6 +3912,8 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc);
intel_disable_primary_hw_plane(dev_priv, plane, pipe);
+
+ assert_vblank_disabled(intel_crtc);
}
static void ironlake_crtc_enable(struct drm_crtc *crtc)
--
1.8.5.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes
2014-05-20 14:20 [PATCH 0/3] drm/i915: A few more vblank interrupt fixes ville.syrjala
2014-05-20 14:20 ` [PATCH 1/3] drm: Always reject drm_vblank_get() after drm_vblank_off() ville.syrjala
2014-05-20 14:20 ` [PATCH 2/3] drm/i915: Warn if drm_vblank_get() still works " ville.syrjala
@ 2014-05-20 14:20 ` ville.syrjala
2014-05-20 17:31 ` [Intel-gfx] " Daniel Vetter
2 siblings, 1 reply; 6+ messages in thread
From: ville.syrjala @ 2014-05-20 14:20 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
If a pipe is already active when we init/resume there might not be a
full modeset afterwards so drm_vblank_on() may not get called. In such
a case if someone is holding a vblank reference across a suspend/resume
cycle drm_vblank_get() called after resuming won't re-enable the vblank
interrupts.
So in order to make sure vblank interrupts get re-enabled post-resume,
call drm_vblank_on() in intel_sanitize_crtc() if the crtc is already
active.
v2: Also drm_vblank_off() if the pipe got disabled magically
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9420f4f..2e9f0b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11708,6 +11708,12 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
reg = PIPECONF(crtc->config.cpu_transcoder);
I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+ /* restore vblank interrupts to correct state */
+ if (crtc->active)
+ drm_vblank_on(dev, crtc->pipe);
+ else
+ drm_vblank_off(dev, crtc->pipe);
+
/* We need to sanitize the plane -> pipe mapping first because this will
* disable the crtc (and hence change the state) if it is wrong. Note
* that gen4+ has a fixed plane -> pipe mapping. */
--
1.8.5.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Intel-gfx] [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes
2014-05-20 14:20 ` [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes ville.syrjala
@ 2014-05-20 17:31 ` Daniel Vetter
2014-05-21 9:50 ` Daniel Vetter
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Vetter @ 2014-05-20 17:31 UTC (permalink / raw)
To: ville.syrjala; +Cc: intel-gfx, dri-devel
On Tue, May 20, 2014 at 05:20:05PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> If a pipe is already active when we init/resume there might not be a
> full modeset afterwards so drm_vblank_on() may not get called. In such
> a case if someone is holding a vblank reference across a suspend/resume
> cycle drm_vblank_get() called after resuming won't re-enable the vblank
> interrupts.
>
> So in order to make sure vblank interrupts get re-enabled post-resume,
> call drm_vblank_on() in intel_sanitize_crtc() if the crtc is already
> active.
>
> v2: Also drm_vblank_off() if the pipe got disabled magically
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
This seems to duct-tape over the funny failure I'm seeing on my snb where
kms_flip/vblank-vs-modeset|dpms-suspend work nicely, but
kms_flip/vblank-vs-suspend has some totally hilarious random vblank frame
counter after the modeset.
Testecase: igt/kms_flip/vblank-vs-suspend
Tested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Now the problem I have: We already call this in the crtc_enable hook. Why
does calling this here again add the necessary magic?
/me has no clue
Cheers, Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9420f4f..2e9f0b0 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11708,6 +11708,12 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> reg = PIPECONF(crtc->config.cpu_transcoder);
> I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
>
> + /* restore vblank interrupts to correct state */
> + if (crtc->active)
> + drm_vblank_on(dev, crtc->pipe);
> + else
> + drm_vblank_off(dev, crtc->pipe);
> +
> /* We need to sanitize the plane -> pipe mapping first because this will
> * disable the crtc (and hence change the state) if it is wrong. Note
> * that gen4+ has a fixed plane -> pipe mapping. */
> --
> 1.8.5.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Intel-gfx] [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes
2014-05-20 17:31 ` [Intel-gfx] " Daniel Vetter
@ 2014-05-21 9:50 ` Daniel Vetter
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Vetter @ 2014-05-21 9:50 UTC (permalink / raw)
To: ville.syrjala; +Cc: intel-gfx, dri-devel
On Tue, May 20, 2014 at 07:31:33PM +0200, Daniel Vetter wrote:
> On Tue, May 20, 2014 at 05:20:05PM +0300, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > If a pipe is already active when we init/resume there might not be a
> > full modeset afterwards so drm_vblank_on() may not get called. In such
> > a case if someone is holding a vblank reference across a suspend/resume
> > cycle drm_vblank_get() called after resuming won't re-enable the vblank
> > interrupts.
> >
> > So in order to make sure vblank interrupts get re-enabled post-resume,
> > call drm_vblank_on() in intel_sanitize_crtc() if the crtc is already
> > active.
> >
> > v2: Also drm_vblank_off() if the pipe got disabled magically
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> This seems to duct-tape over the funny failure I'm seeing on my snb where
> kms_flip/vblank-vs-modeset|dpms-suspend work nicely, but
> kms_flip/vblank-vs-suspend has some totally hilarious random vblank frame
> counter after the modeset.
>
> Testecase: igt/kms_flip/vblank-vs-suspend
> Tested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> Now the problem I have: We already call this in the crtc_enable hook. Why
> does calling this here again add the necessary magic?
>
> /me has no clue
Well, we can figure this out later.
Queued for -next, thanks for the patch.
-Daniel
>
> Cheers, Daniel
> > ---
> > drivers/gpu/drm/i915/intel_display.c | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 9420f4f..2e9f0b0 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -11708,6 +11708,12 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> > reg = PIPECONF(crtc->config.cpu_transcoder);
> > I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
> >
> > + /* restore vblank interrupts to correct state */
> > + if (crtc->active)
> > + drm_vblank_on(dev, crtc->pipe);
> > + else
> > + drm_vblank_off(dev, crtc->pipe);
> > +
> > /* We need to sanitize the plane -> pipe mapping first because this will
> > * disable the crtc (and hence change the state) if it is wrong. Note
> > * that gen4+ has a fixed plane -> pipe mapping. */
> > --
> > 1.8.5.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-05-21 9:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-20 14:20 [PATCH 0/3] drm/i915: A few more vblank interrupt fixes ville.syrjala
2014-05-20 14:20 ` [PATCH 1/3] drm: Always reject drm_vblank_get() after drm_vblank_off() ville.syrjala
2014-05-20 14:20 ` [PATCH 2/3] drm/i915: Warn if drm_vblank_get() still works " ville.syrjala
2014-05-20 14:20 ` [PATCH 3/3] drm/i915: Re-enable vblank irqs for already active pipes ville.syrjala
2014-05-20 17:31 ` [Intel-gfx] " Daniel Vetter
2014-05-21 9:50 ` Daniel Vetter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox