On 8/8/19 1:04 PM, Lyude Paul wrote:
> I -thought- I had fixed this entirely, but it looks like that I didn't
> test this thoroughly enough as we apparently still make one big mistake
> with nv50_msto_atomic_check() - we don't handle the following scenario:
>
> * CRTC #1 has n VCPI allocated to it, is attached to connector DP-4
>    which is attached to encoder #1. enabled=y active=n
> * CRTC #1 is changed from DP-4 to DP-5, causing:
>    * DP-4 crtc=#1→NULL (VCPI n→0)
>    * DP-5 crtc=NULL→#1
>    * CRTC #1 steals encoder #1 back from DP-4 and gives it to DP-5
>    * CRTC #1 maintains the same mode as before, just with a different
>      connector
> * mode_changed=n connectors_changed=y
>    (we _SHOULD_ do VCPI 0→n here, but don't)
>
> Once the above scenario is repeated once, we'll attempt freeing VCPI
> from the connector that we didn't allocate due to the connectors
> changing, but the mode staying the same. Sigh.
>
> Since nv50_msto_atomic_check() has broken a few times now, let's rethink
> things a bit to be more careful: limit both VCPI/PBN allocations to
> mode_changed || connectors_changed, since neither VCPI or PBN should
> ever need to change outside of routing and mode changes.
>
> Signed-off-by: Lyude Paul <[email protected]>
> Reported-by: Bohdan Milar <[email protected]>
> Tested-by: Bohdan Milar <[email protected]>
> Fixes: 232c9eec417a ("drm/nouveau: Use atomic VCPI helpers for MST")
> References: 412e85b60531 ("drm/nouveau: Only release VCPI slots on mode 
> changes")
> Cc: Lyude Paul <[email protected]>
> Cc: Ben Skeggs <[email protected]>
> Cc: Daniel Vetter <[email protected]>
> Cc: David Airlie <[email protected]>
> Cc: Jerry Zuo <[email protected]>
> Cc: Harry Wentland <[email protected]>
> Cc: Juston Li <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Cc: Karol Herbst <[email protected]>
> Cc: Ilia Mirkin <[email protected]>
> Cc: <[email protected]> # v5.1+
> ---
>   drivers/gpu/drm/nouveau/dispnv50/disp.c | 22 +++++++++++++---------
>   1 file changed, 13 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 126703816794..5d23ab8e4917 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -771,16 +771,20 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
>       struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
>       int slots;
>   
> -     /* When restoring duplicated states, we need to make sure that the
> -      * bw remains the same and avoid recalculating it, as the connector's
> -      * bpc may have changed after the state was duplicated
> -      */
> -     if (!state->duplicated)
> -             asyh->dp.pbn =
> -                     drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
> -                                          connector->display_info.bpc * 3);
drm_dp_calc_pbn_mode(clock, bpp)
> +     if (crtc_state->mode_changed || crtc_state->connectors_changed) {
> +             /*
> +              * When restoring duplicated states, we need to make sure that
> +              * the bw remains the same and avoid recalculating it, as the
> +              * connector's bpc may have changed after the state was
> +              * duplicated
> +              */
> +             if (!state->duplicated) {
> +                     const int bpp = connector->display_info.bpc * 3;
> +                     const int clock = crtc_state->adjusted_mode.clock;
> +
> +                     asyh->dp.pbn = drm_dp_calc_pbn_mode(bpp, clock);
drm_dp_calc_pbn_mode(bpp, clock)
> +             }
>   
> -     if (crtc_state->mode_changed) {
>               slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
>                                                     mstc->port,
>                                                     asyh->dp.pbn);
Which is correct?
_______________________________________________
Nouveau mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to