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

2013-02-18 Thread Chris Wilson
On Mon, Feb 18, 2013 at 02:27:24PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 18, 2013 at 12:16:09PM +, 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
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2013-02-18 Thread Ville Syrjälä
On Mon, Feb 18, 2013 at 12:16:09PM +, Chris Wilson wrote:
> On Mon, Feb 18, 2013 at 01:57:51PM +0200, ville.syrj...@linux.intel.com wrote:
> > From: Ville Syrjälä 
> > 
> > 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ä 
> Reviewed-by: Chris Wilson  
> 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
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2013-02-18 Thread Ville Syrjälä
On Mon, Feb 18, 2013 at 01:07:53PM +0100, Paul Menzel wrote:
> Am Montag, den 18.02.2013, 13:57 +0200 schrieb ville.syrj...@linux.intel.com:
> > From: Ville Syrjälä 
> > 
> > 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ä 
> > ---
> >  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
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2013-02-18 Thread Chris Wilson
On Mon, Feb 18, 2013 at 01:57:51PM +0200, ville.syrj...@linux.intel.com wrote:
> From: Ville Syrjälä 
> 
> 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ä 
Reviewed-by: Chris Wilson http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2013-02-18 Thread Paul Menzel
Am Montag, den 18.02.2013, 13:57 +0200 schrieb ville.syrj...@linux.intel.com:
> From: Ville Syrjälä 
> 
> 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ä 
> ---
>  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


signature.asc
Description: This is a digitally signed message part
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2013-02-18 Thread ville . syrjala
From: Ville Syrjälä 

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ä 
---
 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