All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset
@ 2015-02-13 20:03 Daniel Vetter
  2015-02-13 20:03 ` [PATCH 2/5] drm/i915: Drop pipe_enable checks in vblank funcs Daniel Vetter
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-13 20:03 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development
  Cc: Daniel Vetter, Laurent Pinchart, Daniel Vetter

At driver load we need to tell the vblank code about the state of the
pipes, so that the logic around reject vblank_get when the pipe is off
works correctly.

Thus far i915 used drm_vblank_off, but one of the side-effects of it
is that it also saves the vblank counter. And for that it calls down
into the ->get_vblank_counter hook. Which isn't really a good idea
when the pipe is off for a few reasons:
- With runtime pm the register might not respond.
- If the pipe is off some datastructures might not be around or
  unitialized.

The later is what blew up on gen3: We look at intel_crtc->config to
compute the vblank counter, and for a disabled pipe at boot-up that's
just not there. Thus far this was papered over by a check for
intel_crtc->active, but I want to get rid of that (since it's fairly
race, vblank hooks are called from all kinds of places).

So prep for that by adding a _reset functions which only does what we
really need to be done at driver load: Mark the vblank pipe as off,
but don't do any vblank counter saving or event flushing - neither of
that is required.

v2: Clarify the code flow slightly as suggested by Ville.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_irq.c            | 32 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |  6 +++---
 include/drm/drmP.h                   |  1 +
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 75647e7f012b..1e5fb1b994d7 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1226,6 +1226,38 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_vblank_off);
 
 /**
+ * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
+ * @crtc: CRTC in question
+ *
+ * Drivers can use this function to reset the vblank state to off at load time.
+ * Drivers should use this together with the drm_crtc_vblank_off() and
+ * drm_crtc_vblank_on() functions. The diffrence comparet to
+ * drm_crtc_vblank_off() is that this function doesn't save the vblank counter
+ * and hence doesn't need to call any driver hooks.
+ */
+void drm_crtc_vblank_reset(struct drm_crtc *drm_crtc)
+{
+	struct drm_device *dev = drm_crtc->dev;
+	unsigned long irqflags;
+	int crtc = drm_crtc_index(drm_crtc);
+	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
+
+	spin_lock_irqsave(&dev->vbl_lock, irqflags);
+	/*
+	 * Prevent subsequent drm_vblank_get() from enabling the vblank
+	 * interrupt by bumping the refcount.
+	 */
+	if (!vblank->inmodeset) {
+		atomic_inc(&vblank->refcount);
+		vblank->inmodeset = 1;
+	}
+	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+
+	WARN_ON(!list_empty(&dev->vblank_event_list));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_reset);
+
+/**
  * drm_vblank_on - enable vblank events on a CRTC
  * @dev: DRM device
  * @crtc: CRTC in question
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 423ef959264d..8dcf6b512236 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13294,11 +13294,11 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 	I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
 
 	/* restore vblank interrupts to correct state */
+	drm_crtc_vblank_reset(&crtc->base);
 	if (crtc->active) {
 		update_scanline_offset(crtc);
-		drm_vblank_on(dev, crtc->pipe);
-	} else
-		drm_vblank_off(dev, crtc->pipe);
+		drm_crtc_vblank_on(&crtc->base);
+	}
 
 	/* 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
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e928625a9da0..54c6ea1e5866 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -922,6 +922,7 @@ extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
 extern void drm_vblank_off(struct drm_device *dev, int crtc);
 extern void drm_vblank_on(struct drm_device *dev, int crtc);
 extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
+extern void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_on(struct drm_crtc *crtc);
 extern void drm_vblank_cleanup(struct drm_device *dev);
 
-- 
1.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/5] drm/i915: Drop pipe_enable checks in vblank funcs
  2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
@ 2015-02-13 20:03 ` Daniel Vetter
  2015-02-13 20:03 ` [PATCH 3/5] drm/i915: Flatten DRIVER_MODESET checks in i915_irq.c Daniel Vetter
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-13 20:03 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development
  Cc: Daniel Vetter, Laurent Pinchart, Daniel Vetter

With Ville's rework to use drm_crtc_vblank_on/off the core will take
care of rejecting drm_vblank_get calls when the pipe is off. Also the
core won't call the get_vblank_counter hooks in that case either. And
since we've dropped ums support recently we can now remove these
hacks, yay!

Noticed while trying to answer questions Laurent had about how the new
atomic helpers work.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 52 -----------------------------------------
 1 file changed, 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 23bfe2232b6a..80f35dcffea4 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -492,31 +492,6 @@ static void i915_enable_asle_pipestat(struct drm_device *dev)
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
 
-/**
- * i915_pipe_enabled - check if a pipe is enabled
- * @dev: DRM device
- * @pipe: pipe to check
- *
- * Reading certain registers when the pipe is disabled can hang the chip.
- * Use this routine to make sure the PLL is running and the pipe is active
- * before reading such registers if unsure.
- */
-static int
-i915_pipe_enabled(struct drm_device *dev, int pipe)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		/* Locking is horribly broken here, but whatever. */
-		struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-		return intel_crtc->active;
-	} else {
-		return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE;
-	}
-}
-
 /*
  * This timing diagram depicts the video signal in and
  * around the vertical blanking period.
@@ -583,12 +558,6 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 	unsigned long low_frame;
 	u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
 
-	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
-				"pipe %c\n", pipe_name(pipe));
-		return 0;
-	}
-
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		struct intel_crtc *intel_crtc =
 			to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
@@ -648,12 +617,6 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int reg = PIPE_FRMCOUNT_GM45(pipe);
 
-	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
-				 "pipe %c\n", pipe_name(pipe));
-		return 0;
-	}
-
 	return I915_READ(reg);
 }
 
@@ -2660,9 +2623,6 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
-	if (!i915_pipe_enabled(dev, pipe))
-		return -EINVAL;
-
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	if (INTEL_INFO(dev)->gen >= 4)
 		i915_enable_pipestat(dev_priv, pipe,
@@ -2682,9 +2642,6 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
 	uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
 						     DE_PIPE_VBLANK(pipe);
 
-	if (!i915_pipe_enabled(dev, pipe))
-		return -EINVAL;
-
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	ironlake_enable_display_irq(dev_priv, bit);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
@@ -2697,9 +2654,6 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
-	if (!i915_pipe_enabled(dev, pipe))
-		return -EINVAL;
-
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	i915_enable_pipestat(dev_priv, pipe,
 			     PIPE_START_VBLANK_INTERRUPT_STATUS);
@@ -2713,9 +2667,6 @@ static int gen8_enable_vblank(struct drm_device *dev, int pipe)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
-	if (!i915_pipe_enabled(dev, pipe))
-		return -EINVAL;
-
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_VBLANK;
 	I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
@@ -2767,9 +2718,6 @@ static void gen8_disable_vblank(struct drm_device *dev, int pipe)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
-	if (!i915_pipe_enabled(dev, pipe))
-		return;
-
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_VBLANK;
 	I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
-- 
1.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/5] drm/i915: Flatten DRIVER_MODESET checks in i915_irq.c
  2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
  2015-02-13 20:03 ` [PATCH 2/5] drm/i915: Drop pipe_enable checks in vblank funcs Daniel Vetter
@ 2015-02-13 20:03 ` Daniel Vetter
  2015-02-13 20:03 ` [PATCH 4/5] drm/i915: Switch to drm_crtc variants of vblank functions Daniel Vetter
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-13 20:03 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

UMS is no more!

Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 36 +++++++++++-------------------------
 1 file changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 80f35dcffea4..37189a25ca82 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -557,28 +557,16 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 	unsigned long high_frame;
 	unsigned long low_frame;
 	u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+	const struct drm_display_mode *mode =
+		&intel_crtc->config->base.adjusted_mode;
 
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		struct intel_crtc *intel_crtc =
-			to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-		const struct drm_display_mode *mode =
-			&intel_crtc->config->base.adjusted_mode;
-
-		htotal = mode->crtc_htotal;
-		hsync_start = mode->crtc_hsync_start;
-		vbl_start = mode->crtc_vblank_start;
-		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-			vbl_start = DIV_ROUND_UP(vbl_start, 2);
-	} else {
-		enum transcoder cpu_transcoder = (enum transcoder) pipe;
-
-		htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1;
-		hsync_start = (I915_READ(HSYNC(cpu_transcoder))  & 0x1fff) + 1;
-		vbl_start = (I915_READ(VBLANK(cpu_transcoder)) & 0x1fff) + 1;
-		if ((I915_READ(PIPECONF(cpu_transcoder)) &
-		     PIPECONF_INTERLACE_MASK) != PIPECONF_PROGRESSIVE)
-			vbl_start = DIV_ROUND_UP(vbl_start, 2);
-	}
+	htotal = mode->crtc_htotal;
+	hsync_start = mode->crtc_hsync_start;
+	vbl_start = mode->crtc_vblank_start;
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vbl_start = DIV_ROUND_UP(vbl_start, 2);
 
 	/* Convert to pixel count */
 	vbl_start *= htotal;
@@ -4330,10 +4318,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 	if (!IS_GEN2(dev_priv))
 		dev->vblank_disable_immediate = true;
 
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
-		dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
-	}
+	dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+	dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
 
 	if (IS_CHERRYVIEW(dev_priv)) {
 		dev->driver->irq_handler = cherryview_irq_handler;
-- 
1.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/5] drm/i915: Switch to drm_crtc variants of vblank functions
  2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
  2015-02-13 20:03 ` [PATCH 2/5] drm/i915: Drop pipe_enable checks in vblank funcs Daniel Vetter
  2015-02-13 20:03 ` [PATCH 3/5] drm/i915: Flatten DRIVER_MODESET checks in i915_irq.c Daniel Vetter
@ 2015-02-13 20:03 ` Daniel Vetter
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
  2015-02-15 14:08 ` [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Laurent Pinchart
  4 siblings, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-13 20:03 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

Where possible right now. Just a small step towards nirvana ...

v2: git add. Uggh. Noticed by Imre.

Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  | 2 +-
 drivers/gpu/drm/i915/intel_display.c | 9 +++++----
 drivers/gpu/drm/i915/intel_sprite.c  | 4 ++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 3b332a493674..6d69516d4a1c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -580,7 +580,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
 			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
 				   work->flip_queued_vblank,
 				   work->flip_ready_vblank,
-				   drm_vblank_count(dev, crtc->pipe));
+				   drm_crtc_vblank_count(&crtc->base));
 			if (work->enable_stall_check)
 				seq_puts(m, "Stall check enabled, ");
 			else
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8dcf6b512236..0e885383de1d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9674,10 +9674,10 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
 		    !i915_gem_request_completed(work->flip_queued_req, true))
 			return false;
 
-		work->flip_ready_vblank = drm_vblank_count(dev, intel_crtc->pipe);
+		work->flip_ready_vblank = drm_crtc_vblank_count(crtc);
 	}
 
-	if (drm_vblank_count(dev, intel_crtc->pipe) - work->flip_ready_vblank < 3)
+	if (drm_crtc_vblank_count(crtc) - work->flip_ready_vblank < 3)
 		return false;
 
 	/* Potential stall - if we see that the flip has happened,
@@ -9708,7 +9708,8 @@ void intel_check_page_flip(struct drm_device *dev, int pipe)
 	spin_lock(&dev->event_lock);
 	if (intel_crtc->unpin_work && __intel_pageflip_stall_check(dev, crtc)) {
 		WARN_ONCE(1, "Kicking stuck page flip: queued at %d, now %d\n",
-			 intel_crtc->unpin_work->flip_queued_vblank, drm_vblank_count(dev, pipe));
+			 intel_crtc->unpin_work->flip_queued_vblank,
+			 drm_vblank_count(dev, pipe));
 		page_flip_completed(intel_crtc);
 	}
 	spin_unlock(&dev->event_lock);
@@ -9849,7 +9850,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 					intel_ring_get_request(ring));
 	}
 
-	work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
+	work->flip_queued_vblank = drm_crtc_vblank_count(crtc);
 	work->enable_stall_check = true;
 
 	i915_gem_track_fb(work->old_fb_obj, obj,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0a52c44ad03d..d3880b9563c5 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -98,7 +98,7 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
 	if (min <= 0 || max <= 0)
 		return false;
 
-	if (WARN_ON(drm_vblank_get(dev, pipe)))
+	if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
 		return false;
 
 	local_irq_disable();
@@ -132,7 +132,7 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
 
 	finish_wait(wq, &wait);
 
-	drm_vblank_put(dev, pipe);
+	drm_crtc_vblank_put(&crtc->base);
 
 	*start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
 
-- 
1.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
                   ` (2 preceding siblings ...)
  2015-02-13 20:03 ` [PATCH 4/5] drm/i915: Switch to drm_crtc variants of vblank functions Daniel Vetter
@ 2015-02-13 20:03 ` Daniel Vetter
  2015-02-14  9:38   ` shuang.he
                     ` (3 more replies)
  2015-02-15 14:08 ` [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Laurent Pinchart
  4 siblings, 4 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-13 20:03 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

The pipe might already have been shut down, and then it's not a good
idea to call hw accessor functions. Instead use the same logic as
drm_vblank_off which has all the necessary checks to avoid troubles or
inconsistency.

Noticed by Imre while reviewing my patches to remove some sanity
checks from ->get_vblank_counter.

v2: Try harder. disable_and_save can still access the vblank stuff
when vblank->enabled isn't set. It has to, since vlbank irq could be
disable but the pipe is still on when being called from
drm_vblank_off. But we still want to use that code for more code
sharing. So add a check for vblank->enabled on top - if that's not set
we shouldn't have anyone waiting for the vblank. If we have that's a
pretty serious bug.

The other issue that Imre spotted is drm_vblank_cleanup. That code
again calls disable_and_save and so suffers from the same issues. But
really drm_irq_uninstall should have cleaned that all up, so replace
the code with WARN_ON. Note that we can't delete the timer cleanup
since drivers aren't required to use drm_irq_install/uninstall, but
can do their own irq handling.

v3: Make it clear that all that gunk in drm_irq_uninstall is really
just bandaids for UMS races between the irq/vblank code. In UMS
userspace is in control of enabling/disabling interrupts in general
and vblanks specifically.

Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_irq.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 1e5fb1b994d7..885fb756fed5 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -269,7 +269,6 @@ static void vblank_disable_fn(unsigned long arg)
 void drm_vblank_cleanup(struct drm_device *dev)
 {
 	int crtc;
-	unsigned long irqflags;
 
 	/* Bail if the driver didn't call drm_vblank_init() */
 	if (dev->num_crtcs == 0)
@@ -278,11 +277,9 @@ void drm_vblank_cleanup(struct drm_device *dev)
 	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
 
-		del_timer_sync(&vblank->disable_timer);
+		WARN_ON(vblank->enabled);
 
-		spin_lock_irqsave(&dev->vbl_lock, irqflags);
-		vblank_disable_and_save(dev, crtc);
-		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+		del_timer_sync(&vblank->disable_timer);
 	}
 
 	kfree(dev->vblank);
@@ -468,17 +465,23 @@ int drm_irq_uninstall(struct drm_device *dev)
 	dev->irq_enabled = false;
 
 	/*
-	 * Wake up any waiters so they don't hang.
+	 * Wake up any waiters so they don't hang. This is just to paper over
+	 * isssues for UMS drivers which aren't in full control of their
+	 * vblank/irq handling. KMS drivers must ensure that vblanks are all
+	 * disabled when uninstalling the irq handler.
 	 */
 	if (dev->num_crtcs) {
 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
 		for (i = 0; i < dev->num_crtcs; i++) {
 			struct drm_vblank_crtc *vblank = &dev->vblank[i];
 
+			if (!vblank->enabled)
+				continue;
+
+			WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
+
+			vblank_disable_and_save(dev, i);
 			wake_up(&vblank->queue);
-			vblank->enabled = false;
-			vblank->last =
-				dev->driver->get_vblank_counter(dev, i);
 		}
 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 	}
-- 
1.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
@ 2015-02-14  9:38   ` shuang.he
  2015-02-17 13:42   ` Imre Deak
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-14  9:38 UTC (permalink / raw)
  To: shuang.he, ethan.gao, intel-gfx, daniel.vetter

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5777
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                 -1              281/281              280/281
ILK                                  313/313              313/313
SNB                                  309/309              309/309
IVB                                  382/382              382/382
BYT                                  296/296              296/296
HSW                                  426/426              426/426
BDW                 -1              318/318              317/318
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*PNV  igt_gen3_render_mixed_blits      PASS(2)      CRASH(1)PASS(1)
*BDW  igt_gem_gtt_hog      PASS(1)      DMESG_WARN(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset
  2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
                   ` (3 preceding siblings ...)
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
@ 2015-02-15 14:08 ` Laurent Pinchart
  2015-02-23  9:54   ` Daniel Vetter
  4 siblings, 1 reply; 15+ messages in thread
From: Laurent Pinchart @ 2015-02-15 14:08 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development, DRI Development, Daniel Vetter

Hi Daniel,

Thank you for the patch.

On Friday 13 February 2015 21:03:42 Daniel Vetter wrote:
> At driver load we need to tell the vblank code about the state of the
> pipes, so that the logic around reject vblank_get when the pipe is off
> works correctly.
> 
> Thus far i915 used drm_vblank_off, but one of the side-effects of it
> is that it also saves the vblank counter. And for that it calls down
> into the ->get_vblank_counter hook. Which isn't really a good idea
> when the pipe is off for a few reasons:
> - With runtime pm the register might not respond.
> - If the pipe is off some datastructures might not be around or
>   unitialized.
> 
> The later is what blew up on gen3: We look at intel_crtc->config to
> compute the vblank counter, and for a disabled pipe at boot-up that's
> just not there. Thus far this was papered over by a check for
> intel_crtc->active, but I want to get rid of that (since it's fairly
> race, vblank hooks are called from all kinds of places).
> 
> So prep for that by adding a _reset functions which only does what we
> really need to be done at driver load: Mark the vblank pipe as off,
> but don't do any vblank counter saving or event flushing - neither of
> that is required.
> 
> v2: Clarify the code flow slightly as suggested by Ville.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_irq.c            | 32 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |  6 +++---
>  include/drm/drmP.h                   |  1 +
>  3 files changed, 36 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 75647e7f012b..1e5fb1b994d7 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -1226,6 +1226,38 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
>  EXPORT_SYMBOL(drm_crtc_vblank_off);
> 
>  /**
> + * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
> + * @crtc: CRTC in question
> + *
> + * Drivers can use this function to reset the vblank state to off at load
> time.
> + * Drivers should use this together with the drm_crtc_vblank_off() and
> + * drm_crtc_vblank_on() functions. The diffrence comparet to

s/diffrence comparet/difference compared/

With that fixed,

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> + * drm_crtc_vblank_off() is that this function doesn't save the vblank
> counter
> + * and hence doesn't need to call any driver hooks.
> + */
> +void drm_crtc_vblank_reset(struct drm_crtc *drm_crtc)
> +{
> +	struct drm_device *dev = drm_crtc->dev;
> +	unsigned long irqflags;
> +	int crtc = drm_crtc_index(drm_crtc);
> +	struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
> +
> +	spin_lock_irqsave(&dev->vbl_lock, irqflags);
> +	/*
> +	 * Prevent subsequent drm_vblank_get() from enabling the vblank
> +	 * interrupt by bumping the refcount.
> +	 */
> +	if (!vblank->inmodeset) {
> +		atomic_inc(&vblank->refcount);
> +		vblank->inmodeset = 1;
> +	}
> +	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> +
> +	WARN_ON(!list_empty(&dev->vblank_event_list));
> +}
> +EXPORT_SYMBOL(drm_crtc_vblank_reset);
> +
> +/**
>   * drm_vblank_on - enable vblank events on a CRTC
>   * @dev: DRM device
>   * @crtc: CRTC in question
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c index 423ef959264d..8dcf6b512236
> 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13294,11 +13294,11 @@ static void intel_sanitize_crtc(struct intel_crtc
> *crtc) I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
> 
>  	/* restore vblank interrupts to correct state */
> +	drm_crtc_vblank_reset(&crtc->base);
>  	if (crtc->active) {
>  		update_scanline_offset(crtc);
> -		drm_vblank_on(dev, crtc->pipe);
> -	} else
> -		drm_vblank_off(dev, crtc->pipe);
> +		drm_crtc_vblank_on(&crtc->base);
> +	}
> 
>  	/* 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
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index e928625a9da0..54c6ea1e5866 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -922,6 +922,7 @@ extern void drm_crtc_wait_one_vblank(struct drm_crtc
> *crtc); extern void drm_vblank_off(struct drm_device *dev, int crtc);
>  extern void drm_vblank_on(struct drm_device *dev, int crtc);
>  extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
> +extern void drm_crtc_vblank_reset(struct drm_crtc *crtc);
>  extern void drm_crtc_vblank_on(struct drm_crtc *crtc);
>  extern void drm_vblank_cleanup(struct drm_device *dev);

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
  2015-02-14  9:38   ` shuang.he
@ 2015-02-17 13:42   ` Imre Deak
  2015-02-22 11:17   ` [PATCH] " Daniel Vetter
  2015-02-22 14:11   ` [PATCH 1/2] " Daniel Vetter
  3 siblings, 0 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-17 13:42 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On pe, 2015-02-13 at 21:03 +0100, Daniel Vetter wrote:
> The pipe might already have been shut down, and then it's not a good
> idea to call hw accessor functions. Instead use the same logic as
> drm_vblank_off which has all the necessary checks to avoid troubles or
> inconsistency.
> 
> Noticed by Imre while reviewing my patches to remove some sanity
> checks from ->get_vblank_counter.
> 
> v2: Try harder. disable_and_save can still access the vblank stuff
> when vblank->enabled isn't set. It has to, since vlbank irq could be
> disable but the pipe is still on when being called from
> drm_vblank_off. But we still want to use that code for more code
> sharing. So add a check for vblank->enabled on top - if that's not set
> we shouldn't have anyone waiting for the vblank. If we have that's a
> pretty serious bug.
> 
> The other issue that Imre spotted is drm_vblank_cleanup. That code
> again calls disable_and_save and so suffers from the same issues. But
> really drm_irq_uninstall should have cleaned that all up, so replace
> the code with WARN_ON. Note that we can't delete the timer cleanup
> since drivers aren't required to use drm_irq_install/uninstall, but
> can do their own irq handling.
> 
> v3: Make it clear that all that gunk in drm_irq_uninstall is really
> just bandaids for UMS races between the irq/vblank code. In UMS
> userspace is in control of enabling/disabling interrupts in general
> and vblanks specifically.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_irq.c | 21 ++++++++++++---------
>  1 file changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 1e5fb1b994d7..885fb756fed5 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -269,7 +269,6 @@ static void vblank_disable_fn(unsigned long arg)
>  void drm_vblank_cleanup(struct drm_device *dev)
>  {
>  	int crtc;
> -	unsigned long irqflags;
>  
>  	/* Bail if the driver didn't call drm_vblank_init() */
>  	if (dev->num_crtcs == 0)
> @@ -278,11 +277,9 @@ void drm_vblank_cleanup(struct drm_device *dev)
>  	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
>  		struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
>  
> -		del_timer_sync(&vblank->disable_timer);
> +		WARN_ON(vblank->enabled);
>  
> -		spin_lock_irqsave(&dev->vbl_lock, irqflags);
> -		vblank_disable_and_save(dev, crtc);
> -		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> +		del_timer_sync(&vblank->disable_timer);
>  	}

Looking also at non-i915 drivers, drm_vblank_cleanup is called always
before drm_irq_uninstall. Due to 'dev->num_crtcs = 0' in
drm_vblank_cleanup the loop in drm_irq_uninstall will be bypassed and
vblank_disable_and_save won't be called. This is mainly a concern for
UMS as you commented below, but if we care about that I'd prefer doing
the same thing above as you did in drm_irq_uninstall. Don't do anything
if vblanks are disabled otherwise warn only for KMS and call
vblank_disable_and_save and wake_up the vblank queue.

With that this series looks ok to me.

>  
>  	kfree(dev->vblank);
> @@ -468,17 +465,23 @@ int drm_irq_uninstall(struct drm_device *dev)
>  	dev->irq_enabled = false;
>  
>  	/*
> -	 * Wake up any waiters so they don't hang.
> +	 * Wake up any waiters so they don't hang. This is just to paper over
> +	 * isssues for UMS drivers which aren't in full control of their
> +	 * vblank/irq handling. KMS drivers must ensure that vblanks are all
> +	 * disabled when uninstalling the irq handler.
>  	 */
>  	if (dev->num_crtcs) {
>  		spin_lock_irqsave(&dev->vbl_lock, irqflags);
>  		for (i = 0; i < dev->num_crtcs; i++) {
>  			struct drm_vblank_crtc *vblank = &dev->vblank[i];
>  
> +			if (!vblank->enabled)
> +				continue;
> +
> +			WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
> +
> +			vblank_disable_and_save(dev, i);
>  			wake_up(&vblank->queue);
> -			vblank->enabled = false;
> -			vblank->last =
> -				dev->driver->get_vblank_counter(dev, i);
>  		}
>  		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
>  	}


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
  2015-02-14  9:38   ` shuang.he
  2015-02-17 13:42   ` Imre Deak
@ 2015-02-22 11:17   ` Daniel Vetter
  2015-02-23  0:20     ` shuang.he
  2015-02-22 14:11   ` [PATCH 1/2] " Daniel Vetter
  3 siblings, 1 reply; 15+ messages in thread
From: Daniel Vetter @ 2015-02-22 11:17 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

The pipe might already have been shut down, and then it's not a good
idea to call hw accessor functions. Instead use the same logic as
drm_vblank_off which has all the necessary checks to avoid troubles or
inconsistency.

Noticed by Imre while reviewing my patches to remove some sanity
checks from ->get_vblank_counter.

v2: Try harder. disable_and_save can still access the vblank stuff
when vblank->enabled isn't set. It has to, since vlbank irq could be
disable but the pipe is still on when being called from
drm_vblank_off. But we still want to use that code for more code
sharing. So add a check for vblank->enabled on top - if that's not set
we shouldn't have anyone waiting for the vblank. If we have that's a
pretty serious bug.

The other issue that Imre spotted is drm_vblank_cleanup. That code
again calls disable_and_save and so suffers from the same issues. But
really drm_irq_uninstall should have cleaned that all up, so replace
the code with WARN_ON. Note that we can't delete the timer cleanup
since drivers aren't required to use drm_irq_install/uninstall, but
can do their own irq handling.

v3: Make it clear that all that gunk in drm_irq_uninstall is really
just bandaids for UMS races between the irq/vblank code. In UMS
userspace is in control of enabling/disabling interrupts in general
and vblanks specifically.

v4: Imre observed that KMS drivers all call drm_vblank_cleanup before
drm_irq_uninstall (as they should), so again the code in there is dead
for KMS (due to dev->num_crtcs == 0 after drm_vblank_cleanup). Or
should be, so only WARN for KMS - with UMS userspace could try to do
evil things.

Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_irq.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 1e5fb1b994d7..5a8a63abe7d0 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -269,7 +269,6 @@ static void vblank_disable_fn(unsigned long arg)
 void drm_vblank_cleanup(struct drm_device *dev)
 {
 	int crtc;
-	unsigned long irqflags;
 
 	/* Bail if the driver didn't call drm_vblank_init() */
 	if (dev->num_crtcs == 0)
@@ -278,11 +277,12 @@ void drm_vblank_cleanup(struct drm_device *dev)
 	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
 
-		del_timer_sync(&vblank->disable_timer);
+		if (!vblank->enabled)
+			continue;
 
-		spin_lock_irqsave(&dev->vbl_lock, irqflags);
-		vblank_disable_and_save(dev, crtc);
-		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+		WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
+
+		del_timer_sync(&vblank->disable_timer);
 	}
 
 	kfree(dev->vblank);
@@ -468,17 +468,23 @@ int drm_irq_uninstall(struct drm_device *dev)
 	dev->irq_enabled = false;
 
 	/*
-	 * Wake up any waiters so they don't hang.
+	 * Wake up any waiters so they don't hang. This is just to paper over
+	 * isssues for UMS drivers which aren't in full control of their
+	 * vblank/irq handling. KMS drivers must ensure that vblanks are all
+	 * disabled when uninstalling the irq handler.
 	 */
 	if (dev->num_crtcs) {
 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
 		for (i = 0; i < dev->num_crtcs; i++) {
 			struct drm_vblank_crtc *vblank = &dev->vblank[i];
 
+			if (!vblank->enabled)
+				continue;
+
+			WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
+
+			vblank_disable_and_save(dev, i);
 			wake_up(&vblank->queue);
-			vblank->enabled = false;
-			vblank->last =
-				dev->driver->get_vblank_counter(dev, i);
 		}
 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 	}
-- 
1.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 1/2] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
                     ` (2 preceding siblings ...)
  2015-02-22 11:17   ` [PATCH] " Daniel Vetter
@ 2015-02-22 14:11   ` Daniel Vetter
  2015-02-22 14:11     ` [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously Daniel Vetter
  3 siblings, 1 reply; 15+ messages in thread
From: Daniel Vetter @ 2015-02-22 14:11 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

The pipe might already have been shut down, and then it's not a good
idea to call hw accessor functions. Instead use the same logic as
drm_vblank_off which has all the necessary checks to avoid troubles or
inconsistency.

Noticed by Imre while reviewing my patches to remove some sanity
checks from ->get_vblank_counter.

v2: Try harder. disable_and_save can still access the vblank stuff
when vblank->enabled isn't set. It has to, since vlbank irq could be
disable but the pipe is still on when being called from
drm_vblank_off. But we still want to use that code for more code
sharing. So add a check for vblank->enabled on top - if that's not set
we shouldn't have anyone waiting for the vblank. If we have that's a
pretty serious bug.

The other issue that Imre spotted is drm_vblank_cleanup. That code
again calls disable_and_save and so suffers from the same issues. But
really drm_irq_uninstall should have cleaned that all up, so replace
the code with WARN_ON. Note that we can't delete the timer cleanup
since drivers aren't required to use drm_irq_install/uninstall, but
can do their own irq handling.

v3: Make it clear that all that gunk in drm_irq_uninstall is really
just bandaids for UMS races between the irq/vblank code. In UMS
userspace is in control of enabling/disabling interrupts in general
and vblanks specifically.

v4: Imre observed that KMS drivers all call drm_vblank_cleanup before
drm_irq_uninstall (as they should), so again the code in there is dead
for KMS (due to dev->num_crtcs == 0 after drm_vblank_cleanup). Or
should be, so only WARN for KMS - with UMS userspace could try to do
evil things.

v5: After more discussion on irc we've gone back to v3: the
del_timer_sync is required in all cases in drm_vblank_cleanup, but
let's restrict the WARN_ON to kms drivers only. Imre was also
concerned that bad things could happen without the disable_and_save
call. But we immediately free vblank structures afterwards which makes
the save useless. And drm_handle_vblank has a check for dev->num_crtcs
to avoid surprises with ums.

Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_irq.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 1e5fb1b994d7..3c18e522cc3b 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -269,7 +269,6 @@ static void vblank_disable_fn(unsigned long arg)
 void drm_vblank_cleanup(struct drm_device *dev)
 {
 	int crtc;
-	unsigned long irqflags;
 
 	/* Bail if the driver didn't call drm_vblank_init() */
 	if (dev->num_crtcs == 0)
@@ -278,11 +277,10 @@ void drm_vblank_cleanup(struct drm_device *dev)
 	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
 
-		del_timer_sync(&vblank->disable_timer);
+		WARN_ON(vblank->enabled &&
+			drm_core_check_feature(dev, DRIVER_MODESET));
 
-		spin_lock_irqsave(&dev->vbl_lock, irqflags);
-		vblank_disable_and_save(dev, crtc);
-		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+		del_timer_sync(&vblank->disable_timer);
 	}
 
 	kfree(dev->vblank);
@@ -468,17 +466,23 @@ int drm_irq_uninstall(struct drm_device *dev)
 	dev->irq_enabled = false;
 
 	/*
-	 * Wake up any waiters so they don't hang.
+	 * Wake up any waiters so they don't hang. This is just to paper over
+	 * isssues for UMS drivers which aren't in full control of their
+	 * vblank/irq handling. KMS drivers must ensure that vblanks are all
+	 * disabled when uninstalling the irq handler.
 	 */
 	if (dev->num_crtcs) {
 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
 		for (i = 0; i < dev->num_crtcs; i++) {
 			struct drm_vblank_crtc *vblank = &dev->vblank[i];
 
+			if (!vblank->enabled)
+				continue;
+
+			WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
+
+			vblank_disable_and_save(dev, i);
 			wake_up(&vblank->queue);
-			vblank->enabled = false;
-			vblank->last =
-				dev->driver->get_vblank_counter(dev, i);
 		}
 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 	}
-- 
1.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously
  2015-02-22 14:11   ` [PATCH 1/2] " Daniel Vetter
@ 2015-02-22 14:11     ` Daniel Vetter
  2015-02-23  2:26       ` shuang.he
  2015-02-23  9:52       ` Daniel Vetter
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-22 14:11 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

KMS drivers are in full control of their irq and vblank handling, if
they get a vblank interrupt before drm_vblank_init or after
drm_vblank_cleanup that's just a driver bug.

For ums driver there's only r128 and radeon which support vblank, and
they call drm_vblank_init in their driver load functions. Which again
means that userspace can do whatever it wants with interrupt, vblank
structures will always be there.

So this should never happen, let's catch driver issues with a WARN_ON.
Motivated by some discussions with Imre.

v2: Use WARN_ON_ONCE as suggested by Imre.

Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 3c18e522cc3b..dbece03979f3 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1682,7 +1682,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
 	struct timeval tvblank;
 	unsigned long irqflags;
 
-	if (!dev->num_crtcs)
+	if (WARN_ON_ONCE(!dev->num_crtcs))
 		return false;
 
 	if (WARN_ON(crtc >= dev->num_crtcs))
-- 
1.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup
  2015-02-22 11:17   ` [PATCH] " Daniel Vetter
@ 2015-02-23  0:20     ` shuang.he
  0 siblings, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-23  0:20 UTC (permalink / raw)
  To: shuang.he, ethan.gao, intel-gfx, daniel.vetter

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5805
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                 -3              277/277              274/277
ILK                                  313/313              313/313
SNB                                  309/309              309/309
IVB                                  382/382              382/382
BYT                                  296/296              296/296
HSW                                  425/425              425/425
BDW                 -1              318/318              317/318
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*PNV  igt_drm_vma_limiter      PASS(2)      TIMEOUT(1)PASS(1)
*PNV  igt_drm_vma_limiter_cached      NRUN(1)PASS(2)      FAIL(1)PASS(1)
 PNV  igt_gem_userptr_blits_coherency-sync      NO_RESULT(1)CRASH(8)NRUN(1)PASS(8)      CRASH(2)
*BDW  igt_gem_gtt_hog      PASS(23)      DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously
  2015-02-22 14:11     ` [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously Daniel Vetter
@ 2015-02-23  2:26       ` shuang.he
  2015-02-23  9:52       ` Daniel Vetter
  1 sibling, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-23  2:26 UTC (permalink / raw)
  To: shuang.he, ethan.gao, intel-gfx, daniel.vetter

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5807
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                 -3              277/277              274/277
ILK                                  313/313              313/313
SNB                 -23              309/309              286/309
IVB                                  382/382              382/382
BYT                                  296/296              296/296
HSW                 -1              425/425              424/425
BDW                 -1              318/318              317/318
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
 PNV  igt_gem_userptr_blits_coherency-sync      NO_RESULT(1)CRASH(8)NRUN(1)PASS(8)      CRASH(2)
 PNV  igt_gem_userptr_blits_coherency-unsync      CRASH(5)NRUN(1)PASS(6)      CRASH(1)PASS(1)
*PNV  igt_gem_userptr_blits_forked-access      PASS(3)      FAIL(1)PASS(1)
*SNB  igt_gem_fence_thrash_bo-copy      PASS(2)      DMESG_WARN(1)PASS(1)
 SNB  igt_kms_pipe_crc_basic_read-crc-pipe-A      DMESG_WARN(1)PASS(2)      DMESG_WARN(2)
 SNB  igt_kms_pipe_crc_basic_read-crc-pipe-A-frame-sequence      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_pipe_crc_basic_read-crc-pipe-B      DMESG_WARN(1)PASS(2)      DMESG_WARN(2)
 SNB  igt_kms_pipe_crc_basic_read-crc-pipe-B-frame-sequence      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-bottom-right-pipe-A-plane-1      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-bottom-right-pipe-A-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-bottom-right-pipe-B-plane-1      DMESG_WARN(1)PASS(2)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-bottom-right-pipe-B-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-top-left-pipe-A-plane-1      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-top-left-pipe-A-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-top-left-pipe-B-plane-1      DMESG_WARN(1)PASS(2)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-panning-top-left-pipe-B-plane-2      DMESG_WARN(1)PASS(17)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-covered-pipe-A-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-covered-pipe-B-plane-1      DMESG_WARN(1)PASS(2)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-covered-pipe-B-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-hole-pipe-A-plane-1      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-hole-pipe-A-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-hole-pipe-B-plane-1      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_kms_plane_plane-position-hole-pipe-B-plane-2      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_pm_rpm_debugfs-forcewake-user      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_pm_rpm_gem-idle      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 SNB  igt_pm_rpm_reg-read-ioctl      DMESG_WARN(1)PASS(1)      DMESG_WARN(2)
 HSW  igt_kms_flip_plain-flip-fb-recreate      TIMEOUT(4)PASS(3)      TIMEOUT(1)PASS(1)
*BDW  igt_gem_gtt_hog      PASS(23)      DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously
  2015-02-22 14:11     ` [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously Daniel Vetter
  2015-02-23  2:26       ` shuang.he
@ 2015-02-23  9:52       ` Daniel Vetter
  1 sibling, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-23  9:52 UTC (permalink / raw)
  To: Intel Graphics Development, DRI Development; +Cc: Daniel Vetter, Daniel Vetter

On Sun, Feb 22, 2015 at 03:11:20PM +0100, Daniel Vetter wrote:
> KMS drivers are in full control of their irq and vblank handling, if
> they get a vblank interrupt before drm_vblank_init or after
> drm_vblank_cleanup that's just a driver bug.
> 
> For ums driver there's only r128 and radeon which support vblank, and
> they call drm_vblank_init in their driver load functions. Which again
> means that userspace can do whatever it wants with interrupt, vblank
> structures will always be there.
> 
> So this should never happen, let's catch driver issues with a WARN_ON.
> Motivated by some discussions with Imre.
> 
> v2: Use WARN_ON_ONCE as suggested by Imre.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Merged the entire series to dinq with Dave's irc-ack for the core bits.
Thanks a lot for the review feedback.
-Daniel

> ---
>  drivers/gpu/drm/drm_irq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 3c18e522cc3b..dbece03979f3 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -1682,7 +1682,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
>  	struct timeval tvblank;
>  	unsigned long irqflags;
>  
> -	if (!dev->num_crtcs)
> +	if (WARN_ON_ONCE(!dev->num_crtcs))
>  		return false;
>  
>  	if (WARN_ON(crtc >= dev->num_crtcs))
> -- 
> 1.9.3
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset
  2015-02-15 14:08 ` [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Laurent Pinchart
@ 2015-02-23  9:54   ` Daniel Vetter
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-23  9:54 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Sun, Feb 15, 2015 at 04:08:31PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> Thank you for the patch.
> 
> On Friday 13 February 2015 21:03:42 Daniel Vetter wrote:
> > At driver load we need to tell the vblank code about the state of the
> > pipes, so that the logic around reject vblank_get when the pipe is off
> > works correctly.
> > 
> > Thus far i915 used drm_vblank_off, but one of the side-effects of it
> > is that it also saves the vblank counter. And for that it calls down
> > into the ->get_vblank_counter hook. Which isn't really a good idea
> > when the pipe is off for a few reasons:
> > - With runtime pm the register might not respond.
> > - If the pipe is off some datastructures might not be around or
> >   unitialized.
> > 
> > The later is what blew up on gen3: We look at intel_crtc->config to
> > compute the vblank counter, and for a disabled pipe at boot-up that's
> > just not there. Thus far this was papered over by a check for
> > intel_crtc->active, but I want to get rid of that (since it's fairly
> > race, vblank hooks are called from all kinds of places).
> > 
> > So prep for that by adding a _reset functions which only does what we
> > really need to be done at driver load: Mark the vblank pipe as off,
> > but don't do any vblank counter saving or event flushing - neither of
> > that is required.
> > 
> > v2: Clarify the code flow slightly as suggested by Ville.
> > 
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Imre Deak <imre.deak@intel.com>
> > Reviewed-by: Imre Deak <imre.deak@intel.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_irq.c            | 32 ++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c |  6 +++---
> >  include/drm/drmP.h                   |  1 +
> >  3 files changed, 36 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> > index 75647e7f012b..1e5fb1b994d7 100644
> > --- a/drivers/gpu/drm/drm_irq.c
> > +++ b/drivers/gpu/drm/drm_irq.c
> > @@ -1226,6 +1226,38 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> >  EXPORT_SYMBOL(drm_crtc_vblank_off);
> > 
> >  /**
> > + * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
> > + * @crtc: CRTC in question
> > + *
> > + * Drivers can use this function to reset the vblank state to off at load
> > time.
> > + * Drivers should use this together with the drm_crtc_vblank_off() and
> > + * drm_crtc_vblank_on() functions. The diffrence comparet to
> 
> s/diffrence comparet/difference compared/
> 
> With that fixed,
> 
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Fixed while applying, thanks for the feedback.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-02-23  9:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-13 20:03 [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Daniel Vetter
2015-02-13 20:03 ` [PATCH 2/5] drm/i915: Drop pipe_enable checks in vblank funcs Daniel Vetter
2015-02-13 20:03 ` [PATCH 3/5] drm/i915: Flatten DRIVER_MODESET checks in i915_irq.c Daniel Vetter
2015-02-13 20:03 ` [PATCH 4/5] drm/i915: Switch to drm_crtc variants of vblank functions Daniel Vetter
2015-02-13 20:03 ` [PATCH 5/5] drm/irq: Don't call ->get_vblank_counter directly from irq_uninstall/cleanup Daniel Vetter
2015-02-14  9:38   ` shuang.he
2015-02-17 13:42   ` Imre Deak
2015-02-22 11:17   ` [PATCH] " Daniel Vetter
2015-02-23  0:20     ` shuang.he
2015-02-22 14:11   ` [PATCH 1/2] " Daniel Vetter
2015-02-22 14:11     ` [PATCH 2/2] drm: WARN if drm_handle_vblank is called errornously Daniel Vetter
2015-02-23  2:26       ` shuang.he
2015-02-23  9:52       ` Daniel Vetter
2015-02-15 14:08 ` [PATCH 1/5] drm/irq: Add drm_crtc_vblank_reset Laurent Pinchart
2015-02-23  9:54   ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.