diff mbox series

drm/i915/psr: Fix PSR2 handling of multiplanar format

Message ID 20211108213807.39865-1-jose.souza@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/psr: Fix PSR2 handling of multiplanar format | expand

Commit Message

Souza, Jose Nov. 8, 2021, 9:38 p.m. UTC
When a plane with a multiplanar format is added to the state by
drm_atomic_add_affected_planes(), only the UV plane is
added, so a intel_atomic_get_new_plane_state() call to get the Y
plane state can return a null pointer.
To fix this, intel_atomic_get_plane_state() should be called and
the return needs to be checked for errors, as it could return a EAGAIN
as other atomic state could be holding the lock for the Y plane.

Other issue with the patch being fixed is that the Y plane is not
being committed to hardware because the corresponded plane bit is not
set in update_planes when UV and Y planes are added to the state by
drm_atomic_add_affected_planes().

Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective fetch support for biplanar formats")
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Comments

Hogander, Jouni Nov. 9, 2021, 10:31 a.m. UTC | #1
On Mon, 2021-11-08 at 13:38 -0800, José Roberto de Souza wrote:
> When a plane with a multiplanar format is added to the state by
> drm_atomic_add_affected_planes(), only the UV plane is
> added, so a intel_atomic_get_new_plane_state() call to get the Y
> plane state can return a null pointer.

I don't understand how this could happen only sometimes? Were you able
to reproduce this somehow?

Generally: checking linked_new_plane_state being valid pointer makes
sense. I'm just wondering how and when this could happen and how that
should be handled. 

> To fix this, intel_atomic_get_plane_state() should be called and
> the return needs to be checked for errors, as it could return a
> EAGAIN
> as other atomic state could be holding the lock for the Y plane.
> 
> Other issue with the patch being fixed is that the Y plane is not
> being committed to hardware because the corresponded plane bit is not
> set in update_planes when UV and Y planes are added to the state by
> drm_atomic_add_affected_planes().

To my understanding this one is already set in
intel_display.c:icl_check_nv12_planes.

> 
> Cc: Jouni Högander <jouni.hogander@intel.com>
> Cc: Mika Kahola <mika.kahola@intel.com>
> Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective fetch
> support for biplanar formats")
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 9d589d471e335..a1a663f362e7d 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1732,13 +1732,17 @@ int intel_psr2_sel_fetch_update(struct
> intel_atomic_state *state,
>  		 * same area for Y plane as well.
>  		 */
>  		if (linked) {
> -			struct intel_plane_state
> *linked_new_plane_state =
> -			  intel_atomic_get_new_plane_state(state,
> linked);
> -			struct drm_rect *linked_sel_fetch_area =
> -			  &linked_new_plane_state->psr2_sel_fetch_area;
> +			struct intel_plane_state
> *linked_new_plane_state;
> +			struct drm_rect *linked_sel_fetch_area;
>  
> +			linked_new_plane_state =
> intel_atomic_get_plane_state(state, linked);
> +			if (IS_ERR(linked_new_plane_state))
> +				return PTR_ERR(linked_new_plane_state);
> +
> +			linked_sel_fetch_area =
> &linked_new_plane_state->psr2_sel_fetch_area;
>  			linked_sel_fetch_area->y1 = sel_fetch_area->y1;
>  			linked_sel_fetch_area->y2 = sel_fetch_area->y2;
> +			crtc_state->update_planes |= BIT(linked->id);
>  		}
>  	}
>
Souza, Jose Nov. 9, 2021, 6:17 p.m. UTC | #2
On Tue, 2021-11-09 at 10:31 +0000, Hogander, Jouni wrote:
> On Mon, 2021-11-08 at 13:38 -0800, José Roberto de Souza wrote:
> > When a plane with a multiplanar format is added to the state by
> > drm_atomic_add_affected_planes(), only the UV plane is
> > added, so a intel_atomic_get_new_plane_state() call to get the Y
> > plane state can return a null pointer.
> 
> I don't understand how this could happen only sometimes? Were you able
> to reproduce this somehow?

here a example:
plane 0 - primary plane with nv12 format
plane 1 - overlay with any format
plane 2 - primary slave

userspace does a flip to overlay, so state do not have the primary plane
but the primary and overlay planes overlap, so the primary is added by drm_atomic_add_affected_planes()...

> 
> Generally: checking linked_new_plane_state being valid pointer makes
> sense. I'm just wondering how and when this could happen and how that
> should be handled.
> 
> > To fix this, intel_atomic_get_plane_state() should be called and
> > the return needs to be checked for errors, as it could return a
> > EAGAIN
> > as other atomic state could be holding the lock for the Y plane.
> > 
> > Other issue with the patch being fixed is that the Y plane is not
> > being committed to hardware because the corresponded plane bit is not
> > set in update_planes when UV and Y planes are added to the state by
> > drm_atomic_add_affected_planes().
> 
> To my understanding this one is already set in
> intel_display.c:icl_check_nv12_planes.

primary plane will be added after this was executed.

> 
> > 
> > Cc: Jouni Högander <jouni.hogander@intel.com>
> > Cc: Mika Kahola <mika.kahola@intel.com>
> > Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective fetch
> > support for biplanar formats")
> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index 9d589d471e335..a1a663f362e7d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -1732,13 +1732,17 @@ int intel_psr2_sel_fetch_update(struct
> > intel_atomic_state *state,
> >                * same area for Y plane as well.
> >                */
> >               if (linked) {
> > -                     struct intel_plane_state
> > *linked_new_plane_state =
> > -                       intel_atomic_get_new_plane_state(state,
> > linked);
> > -                     struct drm_rect *linked_sel_fetch_area =
> > -                       &linked_new_plane_state->psr2_sel_fetch_area;
> > +                     struct intel_plane_state
> > *linked_new_plane_state;
> > +                     struct drm_rect *linked_sel_fetch_area;
> > 
> > +                     linked_new_plane_state =
> > intel_atomic_get_plane_state(state, linked);
> > +                     if (IS_ERR(linked_new_plane_state))
> > +                             return PTR_ERR(linked_new_plane_state);
> > +
> > +                     linked_sel_fetch_area =
> > &linked_new_plane_state->psr2_sel_fetch_area;
> >                       linked_sel_fetch_area->y1 = sel_fetch_area->y1;
> >                       linked_sel_fetch_area->y2 = sel_fetch_area->y2;
> > +                     crtc_state->update_planes |= BIT(linked->id);
> >               }
> >       }
> > 
>
Hogander, Jouni Nov. 10, 2021, 4:05 p.m. UTC | #3
On Tue, 2021-11-09 at 18:17 +0000, Souza, Jose wrote:
> On Tue, 2021-11-09 at 10:31 +0000, Hogander, Jouni wrote:
> > On Mon, 2021-11-08 at 13:38 -0800, José Roberto de Souza wrote:
> > > When a plane with a multiplanar format is added to the state by
> > > drm_atomic_add_affected_planes(), only the UV plane is
> > > added, so a intel_atomic_get_new_plane_state() call to get the Y
> > > plane state can return a null pointer.
> > 
> > I don't understand how this could happen only sometimes? Were you
> > able
> > to reproduce this somehow?
> 
> here a example:
> plane 0 - primary plane with nv12 format
> plane 1 - overlay with any format
> plane 2 - primary slave
> 
> userspace does a flip to overlay, so state do not have the primary
> plane
> but the primary and overlay planes overlap, so the primary is added
> by drm_atomic_add_affected_planes()...

Ok, thank you for the explanation.

> 
> > Generally: checking linked_new_plane_state being valid pointer
> > makes
> > sense. I'm just wondering how and when this could happen and how
> > that
> > should be handled.
> > 
> > > To fix this, intel_atomic_get_plane_state() should be called and
> > > the return needs to be checked for errors, as it could return a
> > > EAGAIN
> > > as other atomic state could be holding the lock for the Y plane.
> > > 
> > > Other issue with the patch being fixed is that the Y plane is not
> > > being committed to hardware because the corresponded plane bit is
> > > not
> > > set in update_planes when UV and Y planes are added to the state
> > > by
> > > drm_atomic_add_affected_planes().
> > 
> > To my understanding this one is already set in
> > intel_display.c:icl_check_nv12_planes.
> 
> primary plane will be added after this was executed.

Ok, but then isn't it a problem also when selective fetch is not in
use?

> 
> > > Cc: Jouni Högander <jouni.hogander@intel.com>
> > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective
> > > fetch
> > > support for biplanar formats")
> > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
> > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > index 9d589d471e335..a1a663f362e7d 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > @@ -1732,13 +1732,17 @@ int intel_psr2_sel_fetch_update(struct
> > > intel_atomic_state *state,
> > >                * same area for Y plane as well.
> > >                */
> > >               if (linked) {
> > > -                     struct intel_plane_state
> > > *linked_new_plane_state =
> > > -                       intel_atomic_get_new_plane_state(state,
> > > linked);
> > > -                     struct drm_rect *linked_sel_fetch_area =
> > > -                       &linked_new_plane_state-
> > > >psr2_sel_fetch_area;
> > > +                     struct intel_plane_state
> > > *linked_new_plane_state;
> > > +                     struct drm_rect *linked_sel_fetch_area;
> > > 
> > > +                     linked_new_plane_state =
> > > intel_atomic_get_plane_state(state, linked);
> > > +                     if (IS_ERR(linked_new_plane_state))
> > > +                             return
> > > PTR_ERR(linked_new_plane_state);
> > > +
> > > +                     linked_sel_fetch_area =
> > > &linked_new_plane_state->psr2_sel_fetch_area;
> > >                       linked_sel_fetch_area->y1 = sel_fetch_area-
> > > >y1;
> > >                       linked_sel_fetch_area->y2 = sel_fetch_area-
> > > >y2;
> > > +                     crtc_state->update_planes |= BIT(linked-
> > > >id);
> > >               }
> > >       }
> > >
Souza, Jose Nov. 10, 2021, 6:16 p.m. UTC | #4
On Wed, 2021-11-10 at 16:05 +0000, Hogander, Jouni wrote:
> On Tue, 2021-11-09 at 18:17 +0000, Souza, Jose wrote:
> > On Tue, 2021-11-09 at 10:31 +0000, Hogander, Jouni wrote:
> > > On Mon, 2021-11-08 at 13:38 -0800, José Roberto de Souza wrote:
> > > > When a plane with a multiplanar format is added to the state by
> > > > drm_atomic_add_affected_planes(), only the UV plane is
> > > > added, so a intel_atomic_get_new_plane_state() call to get the Y
> > > > plane state can return a null pointer.
> > > 
> > > I don't understand how this could happen only sometimes? Were you
> > > able
> > > to reproduce this somehow?
> > 
> > here a example:
> > plane 0 - primary plane with nv12 format
> > plane 1 - overlay with any format
> > plane 2 - primary slave
> > 
> > userspace does a flip to overlay, so state do not have the primary
> > plane
> > but the primary and overlay planes overlap, so the primary is added
> > by drm_atomic_add_affected_planes()...
> 
> Ok, thank you for the explanation.
> 
> > 
> > > Generally: checking linked_new_plane_state being valid pointer
> > > makes
> > > sense. I'm just wondering how and when this could happen and how
> > > that
> > > should be handled.
> > > 
> > > > To fix this, intel_atomic_get_plane_state() should be called and
> > > > the return needs to be checked for errors, as it could return a
> > > > EAGAIN
> > > > as other atomic state could be holding the lock for the Y plane.
> > > > 
> > > > Other issue with the patch being fixed is that the Y plane is not
> > > > being committed to hardware because the corresponded plane bit is
> > > > not
> > > > set in update_planes when UV and Y planes are added to the state
> > > > by
> > > > drm_atomic_add_affected_planes().
> > > 
> > > To my understanding this one is already set in
> > > intel_display.c:icl_check_nv12_planes.
> > 
> > primary plane will be added after this was executed.
> 
> Ok, but then isn't it a problem also when selective fetch is not in
> use?

Yes but it is not common to call drm_atomic_add_affected_planes() or intel_atomic_get_plane_state() that late.

> 
> > 
> > > > Cc: Jouni Högander <jouni.hogander@intel.com>
> > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective
> > > > fetch
> > > > support for biplanar formats")
> > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
> > > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > index 9d589d471e335..a1a663f362e7d 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > @@ -1732,13 +1732,17 @@ int intel_psr2_sel_fetch_update(struct
> > > > intel_atomic_state *state,
> > > >                * same area for Y plane as well.
> > > >                */
> > > >               if (linked) {
> > > > -                     struct intel_plane_state
> > > > *linked_new_plane_state =
> > > > -                       intel_atomic_get_new_plane_state(state,
> > > > linked);
> > > > -                     struct drm_rect *linked_sel_fetch_area =
> > > > -                       &linked_new_plane_state-
> > > > > psr2_sel_fetch_area;
> > > > +                     struct intel_plane_state
> > > > *linked_new_plane_state;
> > > > +                     struct drm_rect *linked_sel_fetch_area;
> > > > 
> > > > +                     linked_new_plane_state =
> > > > intel_atomic_get_plane_state(state, linked);
> > > > +                     if (IS_ERR(linked_new_plane_state))
> > > > +                             return
> > > > PTR_ERR(linked_new_plane_state);
> > > > +
> > > > +                     linked_sel_fetch_area =
> > > > &linked_new_plane_state->psr2_sel_fetch_area;
> > > >                       linked_sel_fetch_area->y1 = sel_fetch_area-
> > > > > y1;
> > > >                       linked_sel_fetch_area->y2 = sel_fetch_area-
> > > > > y2;
> > > > +                     crtc_state->update_planes |= BIT(linked-
> > > > > id);
> > > >               }
> > > >       }
> > > >
Hogander, Jouni Nov. 11, 2021, 6:43 p.m. UTC | #5
Thank you for the clarification.

Reviewed-by: Jouni Högander <jouni.hogander@intel.com>

On Wed, 2021-11-10 at 18:16 +0000, Souza, Jose wrote:
> On Wed, 2021-11-10 at 16:05 +0000, Hogander, Jouni wrote:
> > On Tue, 2021-11-09 at 18:17 +0000, Souza, Jose wrote:
> > > On Tue, 2021-11-09 at 10:31 +0000, Hogander, Jouni wrote:
> > > > On Mon, 2021-11-08 at 13:38 -0800, José Roberto de Souza wrote:
> > > > > When a plane with a multiplanar format is added to the state
> > > > > by
> > > > > drm_atomic_add_affected_planes(), only the UV plane is
> > > > > added, so a intel_atomic_get_new_plane_state() call to get
> > > > > the Y
> > > > > plane state can return a null pointer.
> > > > 
> > > > I don't understand how this could happen only sometimes? Were
> > > > you
> > > > able
> > > > to reproduce this somehow?
> > > 
> > > here a example:
> > > plane 0 - primary plane with nv12 format
> > > plane 1 - overlay with any format
> > > plane 2 - primary slave
> > > 
> > > userspace does a flip to overlay, so state do not have the
> > > primary
> > > plane
> > > but the primary and overlay planes overlap, so the primary is
> > > added
> > > by drm_atomic_add_affected_planes()...
> > 
> > Ok, thank you for the explanation.
> > 
> > > > Generally: checking linked_new_plane_state being valid pointer
> > > > makes
> > > > sense. I'm just wondering how and when this could happen and
> > > > how
> > > > that
> > > > should be handled.
> > > > 
> > > > > To fix this, intel_atomic_get_plane_state() should be called
> > > > > and
> > > > > the return needs to be checked for errors, as it could return
> > > > > a
> > > > > EAGAIN
> > > > > as other atomic state could be holding the lock for the Y
> > > > > plane.
> > > > > 
> > > > > Other issue with the patch being fixed is that the Y plane is
> > > > > not
> > > > > being committed to hardware because the corresponded plane
> > > > > bit is
> > > > > not
> > > > > set in update_planes when UV and Y planes are added to the
> > > > > state
> > > > > by
> > > > > drm_atomic_add_affected_planes().
> > > > 
> > > > To my understanding this one is already set in
> > > > intel_display.c:icl_check_nv12_planes.
> > > 
> > > primary plane will be added after this was executed.
> > 
> > Ok, but then isn't it a problem also when selective fetch is not in
> > use?
> 
> Yes but it is not common to call drm_atomic_add_affected_planes() or
> intel_atomic_get_plane_state() that late.
> 
> > > > > Cc: Jouni Högander <jouni.hogander@intel.com>
> > > > > Cc: Mika Kahola <mika.kahola@intel.com>
> > > > > Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective
> > > > > fetch
> > > > > support for biplanar formats")
> > > > > Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
> > > > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > index 9d589d471e335..a1a663f362e7d 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > > > @@ -1732,13 +1732,17 @@ int
> > > > > intel_psr2_sel_fetch_update(struct
> > > > > intel_atomic_state *state,
> > > > >                * same area for Y plane as well.
> > > > >                */
> > > > >               if (linked) {
> > > > > -                     struct intel_plane_state
> > > > > *linked_new_plane_state =
> > > > > -                       intel_atomic_get_new_plane_state(stat
> > > > > e,
> > > > > linked);
> > > > > -                     struct drm_rect *linked_sel_fetch_area
> > > > > =
> > > > > -                       &linked_new_plane_state-
> > > > > > psr2_sel_fetch_area;
> > > > > +                     struct intel_plane_state
> > > > > *linked_new_plane_state;
> > > > > +                     struct drm_rect *linked_sel_fetch_area;
> > > > > 
> > > > > +                     linked_new_plane_state =
> > > > > intel_atomic_get_plane_state(state, linked);
> > > > > +                     if (IS_ERR(linked_new_plane_state))
> > > > > +                             return
> > > > > PTR_ERR(linked_new_plane_state);
> > > > > +
> > > > > +                     linked_sel_fetch_area =
> > > > > &linked_new_plane_state->psr2_sel_fetch_area;
> > > > >                       linked_sel_fetch_area->y1 =
> > > > > sel_fetch_area-
> > > > > > y1;
> > > > >                       linked_sel_fetch_area->y2 =
> > > > > sel_fetch_area-
> > > > > > y2;
> > > > > +                     crtc_state->update_planes |=
> > > > > BIT(linked-
> > > > > > id);
> > > > >               }
> > > > >       }
> > > > >
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 9d589d471e335..a1a663f362e7d 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1732,13 +1732,17 @@  int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 		 * same area for Y plane as well.
 		 */
 		if (linked) {
-			struct intel_plane_state *linked_new_plane_state =
-			  intel_atomic_get_new_plane_state(state, linked);
-			struct drm_rect *linked_sel_fetch_area =
-			  &linked_new_plane_state->psr2_sel_fetch_area;
+			struct intel_plane_state *linked_new_plane_state;
+			struct drm_rect *linked_sel_fetch_area;
 
+			linked_new_plane_state = intel_atomic_get_plane_state(state, linked);
+			if (IS_ERR(linked_new_plane_state))
+				return PTR_ERR(linked_new_plane_state);
+
+			linked_sel_fetch_area = &linked_new_plane_state->psr2_sel_fetch_area;
 			linked_sel_fetch_area->y1 = sel_fetch_area->y1;
 			linked_sel_fetch_area->y2 = sel_fetch_area->y2;
+			crtc_state->update_planes |= BIT(linked->id);
 		}
 	}