[Intel-gfx] [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Mon Feb 18 12:57:51 CET 2013


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

If the interrupt handler were to process a previous vblank interrupt and
the following flip pending interrupt at the same time, the page flip
would be complete too soon.

To eliminate this race check the live pending flip status from the ISR
register before finishing the page flip.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9fde49a..3de570c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2284,8 +2284,11 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 		    drm_handle_vblank(dev, 0)) {
 			if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
 				intel_prepare_page_flip(dev, 0);
-				intel_finish_page_flip(dev, 0);
-				flip_mask &= ~I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
+
+				if ((I915_READ16(ISR) & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) == 0) {
+					intel_finish_page_flip(dev, 0);
+					flip_mask &= ~I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
+				}
 			}
 		}
 
@@ -2293,8 +2296,11 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 		    drm_handle_vblank(dev, 1)) {
 			if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) {
 				intel_prepare_page_flip(dev, 1);
-				intel_finish_page_flip(dev, 1);
-				flip_mask &= ~I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+
+				if ((I915_READ16(ISR) & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) == 0) {
+					intel_finish_page_flip(dev, 1);
+					flip_mask &= ~I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+				}
 			}
 		}
 
@@ -2491,8 +2497,11 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 			    drm_handle_vblank(dev, pipe)) {
 				if (iir & flip[plane]) {
 					intel_prepare_page_flip(dev, plane);
-					intel_finish_page_flip(dev, pipe);
-					flip_mask &= ~flip[plane];
+
+					if ((I915_READ(ISR) & flip[plane]) == 0) {
+						intel_finish_page_flip(dev, pipe);
+						flip_mask &= ~flip[plane];
+					}
 				}
 			}
 
-- 
1.7.12.4




More information about the Intel-gfx mailing list