public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [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