On 2022-07-28 09:49, Yunxiang Li wrote:
> manage_dm_interrupts disable/enable vblank using drm_crtc_vblank_off/on
> which causes drm_crtc_vblank_get in vrr_transition to fail, and later
> when drm_crtc_vblank_put is called the refcount on vblank will be messed
> up. Therefore move the call to after manage_dm_interrupts.
> 
> Unchecked calls to drm_crtc_vblank_get seems to be common in other
> drivers as well so it may make sense to let get always succeed during
> modset, see
> https://lists.freedesktop.org/archives/dri-devel/2022-July/365589.html
> 

Thanks for this patch.

This change makes sense to me but I would love Mario and/or Nick to take
a look as well, if possible. Would prefer if we hold off on the merge and
give them a chance to chime in.

Reviewed-by: Harry Wentland <harry.wentl...@amd.com>

Harry

> Signed-off-by: Yunxiang Li <yunxiang...@amd.com>
> ---
> v2: check the return code for calls that might fail and warn on them  
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 ++++++++-----------
>  1 file changed, 14 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 92470a0e0262..9f3fdb92e7a4 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -7480,15 +7480,15 @@ static void amdgpu_dm_handle_vrr_transition(struct 
> dm_crtc_state *old_state,
>                * We also need vupdate irq for the actual core vblank handling
>                * at end of vblank.
>                */
> -             dm_set_vupdate_irq(new_state->base.crtc, true);
> -             drm_crtc_vblank_get(new_state->base.crtc);
> +             WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0);
> +             WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0);
>               DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n",
>                                __func__, new_state->base.crtc->base.id);
>       } else if (old_vrr_active && !new_vrr_active) {
>               /* Transition VRR active -> inactive:
>                * Allow vblank irq disable again for fixed refresh rate.
>                */
> -             dm_set_vupdate_irq(new_state->base.crtc, false);
> +             WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0);
>               drm_crtc_vblank_put(new_state->base.crtc);
>               DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n",
>                                __func__, new_state->base.crtc->base.id);
> @@ -8252,23 +8252,6 @@ static void amdgpu_dm_atomic_commit_tail(struct 
> drm_atomic_state *state)
>               mutex_unlock(&dm->dc_lock);
>       }
>  
> -     /* Count number of newly disabled CRTCs for dropping PM refs later. */
> -     for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
> -                                   new_crtc_state, i) {
> -             if (old_crtc_state->active && !new_crtc_state->active)
> -                     crtc_disable_count++;
> -
> -             dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
> -             dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
> -
> -             /* For freesync config update on crtc state and params for irq 
> */
> -             update_stream_irq_parameters(dm, dm_new_crtc_state);
> -
> -             /* Handle vrr on->off / off->on transitions */
> -             amdgpu_dm_handle_vrr_transition(dm_old_crtc_state,
> -                                             dm_new_crtc_state);
> -     }
> -
>       /**
>        * Enable interrupts for CRTCs that are newly enabled or went through
>        * a modeset. It was intentionally deferred until after the front end
> @@ -8287,7 +8270,15 @@ static void amdgpu_dm_atomic_commit_tail(struct 
> drm_atomic_state *state)
>               cur_crc_src = acrtc->dm_irq_params.crc_src;
>               spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
>  #endif
> +             /* Count number of newly disabled CRTCs for dropping PM refs 
> later. */
> +             if (old_crtc_state->active && !new_crtc_state->active)
> +                     crtc_disable_count++;
> +
>               dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
> +             dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
> +
> +             /* For freesync config update on crtc state and params for irq 
> */
> +             update_stream_irq_parameters(dm, dm_new_crtc_state);
>  
>               if (new_crtc_state->active &&
>                   (!old_crtc_state->active ||
> @@ -8324,6 +8315,9 @@ static void amdgpu_dm_atomic_commit_tail(struct 
> drm_atomic_state *state)
>                                       DRM_DEBUG_DRIVER("Failed to configure 
> crc source");
>  #endif
>               }
> +
> +             /* Handle vrr on->off / off->on transitions */
> +             amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, 
> dm_new_crtc_state);
>       }
>  
>       for_each_new_crtc_in_state(state, crtc, new_crtc_state, j)

Reply via email to