Re: [Nouveau] [PATCH] drm/nouveau: Only release VCPI slots on mode changes

From: Ben Skeggs
Date: Thu Aug 01 2019 - 19:46:08 EST


On Fri, 2 Aug 2019 at 08:02, Lyude Paul <lyude@xxxxxxxxxx> wrote:
>
> Looks like a regression got introduced into nv50_mstc_atomic_check()
> that somehow didn't get found until now. If userspace changes
> crtc_state->active to false but leaves the CRTC enabled, we end up
> calling drm_dp_atomic_find_vcpi_slots() using the PBN calculated in
> asyh->dp.pbn. However, if the display is inactive we end up calculating
> a PBN of 0, which inadvertently causes us to have an allocation of 0.
> From there, if userspace then disables the CRTC afterwards we end up
> accidentally attempting to free the VCPI twice:
>
> WARNING: CPU: 0 PID: 1484 at drivers/gpu/drm/drm_dp_mst_topology.c:3336
> drm_dp_atomic_release_vcpi_slots+0x87/0xb0 [drm_kms_helper]
> RIP: 0010:drm_dp_atomic_release_vcpi_slots+0x87/0xb0 [drm_kms_helper]
> Call Trace:
> drm_atomic_helper_check_modeset+0x3f3/0xa60 [drm_kms_helper]
> ? drm_atomic_check_only+0x43/0x780 [drm]
> drm_atomic_helper_check+0x15/0x90 [drm_kms_helper]
> nv50_disp_atomic_check+0x83/0x1d0 [nouveau]
> drm_atomic_check_only+0x54d/0x780 [drm]
> ? drm_atomic_set_crtc_for_connector+0xec/0x100 [drm]
> drm_atomic_commit+0x13/0x50 [drm]
> drm_atomic_helper_set_config+0x81/0x90 [drm_kms_helper]
> drm_mode_setcrtc+0x194/0x6a0 [drm]
> ? vprintk_emit+0x16a/0x230
> ? drm_ioctl+0x163/0x390 [drm]
> ? drm_mode_getcrtc+0x180/0x180 [drm]
> drm_ioctl_kernel+0xaa/0xf0 [drm]
> drm_ioctl+0x208/0x390 [drm]
> ? drm_mode_getcrtc+0x180/0x180 [drm]
> nouveau_drm_ioctl+0x63/0xb0 [nouveau]
> do_vfs_ioctl+0x405/0x660
> ? recalc_sigpending+0x17/0x50
> ? _copy_from_user+0x37/0x60
> ksys_ioctl+0x5e/0x90
> ? exit_to_usermode_loop+0x92/0xe0
> __x64_sys_ioctl+0x16/0x20
> do_syscall_64+0x59/0x190
> entry_SYSCALL_64_after_hwframe+0x44/0xa9
> WARNING: CPU: 0 PID: 1484 at drivers/gpu/drm/drm_dp_mst_topology.c:3336
> drm_dp_atomic_release_vcpi_slots+0x87/0xb0 [drm_kms_helper]
> ---[ end trace 4c395c0c51b1f88d ]---
> [drm:drm_dp_atomic_release_vcpi_slots [drm_kms_helper]] *ERROR* no VCPI for
> [MST PORT:00000000e288eb7d] found in mst state 000000008e642070
>
> So, fix this by doing what we probably should have done from the start: only
> call drm_dp_atomic_find_vcpi_slots() when crtc_state->mode_changed is set, so
> that VCPI allocations remain for as long as the CRTC is enabled.
>
> Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx>
> Fixes: 232c9eec417a ("drm/nouveau: Use atomic VCPI helpers for MST")
> Cc: Lyude Paul <lyude@xxxxxxxxxx>
> Cc: Ben Skeggs <bskeggs@xxxxxxxxxx>
> Cc: Daniel Vetter <daniel.vetter@xxxxxxxx>
> Cc: David Airlie <airlied@xxxxxxxxxx>
> Cc: Jerry Zuo <Jerry.Zuo@xxxxxxx>
> Cc: Harry Wentland <harry.wentland@xxxxxxx>
> Cc: Juston Li <juston.li@xxxxxxxxx>
> Cc: Karol Herbst <karolherbst@xxxxxxxxx>
> Cc: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
> Cc: Ilia Mirkin <imirkin@xxxxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx> # v5.1+
Acked-by: Ben Skeggs <bskeggs@xxxxxxxxxx>

> ---
> drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 8497768f1b41..126703816794 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -780,7 +780,7 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
> drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
> connector->display_info.bpc * 3);
>
> - if (drm_atomic_crtc_needs_modeset(crtc_state)) {
> + if (crtc_state->mode_changed) {
> slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
> mstc->port,
> asyh->dp.pbn);
> --
> 2.21.0
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@xxxxxxxxxxxxxxxxxxxxx
> https://lists.freedesktop.org/mailman/listinfo/nouveau