All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
@ 2013-02-18 11:57 ville.syrjala
  2013-02-18 12:07 ` Paul Menzel
  2013-02-18 12:16 ` Chris Wilson
  0 siblings, 2 replies; 6+ messages in thread
From: ville.syrjala @ 2013-02-18 11:57 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@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@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

_______________________________________________
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: [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
  2013-02-18 11:57 [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling ville.syrjala
@ 2013-02-18 12:07 ` Paul Menzel
  2013-02-18 12:20   ` Ville Syrjälä
  2013-02-18 12:16 ` Chris Wilson
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Menzel @ 2013-02-18 12:07 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2583 bytes --]

Am Montag, den 18.02.2013, 13:57 +0200 schrieb ville.syrjala@linux.intel.com:
> From: Ville Syrjälä <ville.syrjala@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.

»would complete« or »would be complete*d*«

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

Could this be tested somehow? Could a test case be written for this?

> Signed-off-by: Ville Syrjälä <ville.syrjala@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) {

Why not `I915_READ16`?

> +						intel_finish_page_flip(dev, pipe);
> +						flip_mask &= ~flip[plane];
> +					}
>  				}
>  			}


Thanks,

Paul

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

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

* Re: [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
  2013-02-18 11:57 [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling ville.syrjala
  2013-02-18 12:07 ` Paul Menzel
@ 2013-02-18 12:16 ` Chris Wilson
  2013-02-18 12:27   ` Ville Syrjälä
  1 sibling, 1 reply; 6+ messages in thread
From: Chris Wilson @ 2013-02-18 12:16 UTC (permalink / raw)
  To: ville.syrjala; +Cc: intel-gfx

On Mon, Feb 18, 2013 at 01:57:51PM +0200, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@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.

Ok, that makes a lot of sense.

/* We detect FlipDone by looking for the change in PendingFlip from '1'
 * to '0' on the following vblank, i.e. IIR has the Pendingflip
 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
 * the flip is completed (no longer pending). Since this doesn't raise an
 * interrupt per-se, we watch for the change at vblank.
 */
 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wils

Time to give it a quick test and make sure it doesn't break a ton of
assumptions... :)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

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

* Re: [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
  2013-02-18 12:07 ` Paul Menzel
@ 2013-02-18 12:20   ` Ville Syrjälä
  0 siblings, 0 replies; 6+ messages in thread
From: Ville Syrjälä @ 2013-02-18 12:20 UTC (permalink / raw)
  To: Paul Menzel; +Cc: intel-gfx

On Mon, Feb 18, 2013 at 01:07:53PM +0100, Paul Menzel wrote:
> Am Montag, den 18.02.2013, 13:57 +0200 schrieb ville.syrjala@linux.intel.com:
> > From: Ville Syrjälä <ville.syrjala@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.
> 
> »would complete« or »would be complete*d*«

The second on is what I meant. Will fix.

> 
> > To eliminate this race check the live pending flip status from the ISR
> > register before finishing the page flip.
> 
> Could this be tested somehow? Could a test case be written for this?

It shouldn't be too difficult to force it from within the kernel. Just
turn off interrupts before vblank start, wait until vblank start is
passed, execute the MI_DISPLAY_FLIP, and finally turn the interrupts
back on again.

Given the timing constraints I'm not sure we can come up with anything
that would realiably hit it otherwise.

> 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@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) {
> 
> Why not `I915_READ16`?

It matches the rest if i915_irq_handler(). I suppose the interrupt
registers were 16 bit on gen2 and 32 bit on gen3+.

> 
> > +						intel_finish_page_flip(dev, pipe);
> > +						flip_mask &= ~flip[plane];
> > +					}
> >  				}
> >  			}
> 
> 
> Thanks,
> 
> Paul



-- 
Ville Syrjälä
Intel OTC

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

* Re: [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
  2013-02-18 12:16 ` Chris Wilson
@ 2013-02-18 12:27   ` Ville Syrjälä
  2013-02-18 13:19     ` Chris Wilson
  0 siblings, 1 reply; 6+ messages in thread
From: Ville Syrjälä @ 2013-02-18 12:27 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Mon, Feb 18, 2013 at 12:16:09PM +0000, Chris Wilson wrote:
> On Mon, Feb 18, 2013 at 01:57:51PM +0200, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@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.
> 
> Ok, that makes a lot of sense.
> 
> /* We detect FlipDone by looking for the change in PendingFlip from '1'
>  * to '0' on the following vblank, i.e. IIR has the Pendingflip
>  * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
>  * the flip is completed (no longer pending). Since this doesn't raise an
>  * interrupt per-se, we watch for the change at vblank.
>  */

You want me to include that comment somewhere in the code?

> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Reviewed-by: Chris Wilson <chris@chris-wils
> 
> Time to give it a quick test and make sure it doesn't break a ton of
> assumptions... :)
> -Chris
> 
> -- 
> Chris Wilson, Intel Open Source Technology Centre

-- 
Ville Syrjälä
Intel OTC

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

* Re: [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling
  2013-02-18 12:27   ` Ville Syrjälä
@ 2013-02-18 13:19     ` Chris Wilson
  0 siblings, 0 replies; 6+ messages in thread
From: Chris Wilson @ 2013-02-18 13:19 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Feb 18, 2013 at 02:27:24PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 18, 2013 at 12:16:09PM +0000, Chris Wilson wrote:
> > /* We detect FlipDone by looking for the change in PendingFlip from '1'
> >  * to '0' on the following vblank, i.e. IIR has the Pendingflip
> >  * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
> >  * the flip is completed (no longer pending). Since this doesn't raise an
> >  * interrupt per-se, we watch for the change at vblank.
> >  */
> 
> You want me to include that comment somewhere in the code?

Please, would be useful for future archaeologists. I'd pick the gen3
location as it is more compact.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

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

end of thread, other threads:[~2013-02-18 13:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-18 11:57 [PATCH] drm/i915: Eliminate race from gen2/3 page flip interrupt handling ville.syrjala
2013-02-18 12:07 ` Paul Menzel
2013-02-18 12:20   ` Ville Syrjälä
2013-02-18 12:16 ` Chris Wilson
2013-02-18 12:27   ` Ville Syrjälä
2013-02-18 13:19     ` Chris Wilson

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.