All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Cristian Ciocaltea" <cristian.ciocaltea@collabora.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v6 04/15] drm/rockchip: vop2: Balance state on atomic_enable() error paths
Date: Thu, 05 Nov 2026 01:20:44 +0000	[thread overview]
Message-ID: <sashiko-outbox-198400@kernel.org> (raw)
In-Reply-To: <20261105-dw-hdmi-qp-yuv-v6-4-1bb63ef5766e@collabora.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] drm/rockchip: vop2: plane left enabled in vop2_plane_atomic_update()
- [High] drm/rockchip: vop2: unhandled vblank event in vop2_crtc_atomic_flush()
--

commit ad40a8e305ba6e768ae3478a34b5ddce63b79357
Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>

drm/rockchip: vop2: Balance state on atomic_enable() error paths

This commit cleans up clocks, vop2->enable_count, and PM runtime state on
vop2_crtc_atomic_enable() failure paths and introduces a per-video-port
enabled flag so atomic commit callbacks skip hardware programming and
teardown when a CRTC failed to enable.

Link: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/

> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index bc14ca9d598dc..8d5613531acb9 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c

[ ... ]

> @@ -1197,13 +1203,21 @@ static void vop2_plane_atomic_disable(struct drm_plane *plane,
>  	struct drm_plane_state *old_pstate = NULL;
>  	struct vop2_win *win = to_vop2_win(plane);
>  	struct vop2 *vop2 = win->vop2;
> +	struct vop2_video_port *vp;
>  
>  	drm_dbg(vop2->drm, "%s disable\n", win->data->name);
>  
>  	if (state)
>  		old_pstate = drm_atomic_get_old_plane_state(state, plane);
> -	if (old_pstate && !old_pstate->crtc)
> -		return;
> +
> +	if (old_pstate) {
> +		if (!old_pstate->crtc)
> +			return;
> +
> +		vp = to_vop2_video_port(old_pstate->crtc);
> +		if (!vp->enabled)
> +			return;
> +	}
>  
>  	vop2_win_disable(win);
>  	vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
> @@ -1298,6 +1312,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
>  	if (WARN_ON(!crtc))
>  		return;
>  
> +	if (!vp->enabled)
> +		return;
> +
>  	if (!pstate->visible) {
>  		vop2_plane_atomic_disable(plane, state);
>  		return;

[Severity: High]
What happens if an active plane is migrated from an enabled CRTC to another
CRTC whose vop2_crtc_atomic_enable() failed?

When a plane moves between CRTCs, drm_atomic_helper_commit_planes() sees
new_plane_state->crtc != NULL and plane_crtc_active(new_plane_state) == true,
so it calls vop2_plane_atomic_update() rather than
vop2_plane_atomic_disable(). Meanwhile, on the source CRTC,
vop2_crtc_atomic_begin() -> setup_overlay() only iterates over planes in the
source CRTC's new plane_mask and does not disable the migrated window.

In vop2_plane_atomic_update(), vp is derived from the destination CRTC
(pstate->crtc). Returning early when !vp->enabled skips
vop2_plane_atomic_disable(plane, state) and leaves VOP2_WIN_ENABLE set on the
source CRTC while drm_atomic_helper_cleanup_planes() unmaps and releases
old_plane_state->fb at the end of the commit tail, allowing the hardware
window to continue DMA scanout from the old framebuffer.

Since vop2_plane_atomic_disable() already checks old_pstate->crtc and
whether the old video port is enabled before touching hardware registers,
should vop2_plane_atomic_update() call vop2_plane_atomic_disable(plane, state)
when !vp->enabled, just as it does when !pstate->visible?

[ ... ]

> @@ -2034,13 +2066,19 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
>  	struct vop2_video_port *vp = to_vop2_video_port(crtc);
>  	struct vop2 *vop2 = vp->vop2;
>  
> -	/* In case of modeset, gamma lut update already happened in atomic enable */
> -	if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
> -		vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
> +	if (vp->enabled) {
> +		/*
> +		 * In case of modeset, gamma lut update already happened
> +		 * in atomic enable.
> +		 */
> +		if (!drm_atomic_crtc_needs_modeset(crtc_state) &&
> +		    crtc_state->color_mgmt_changed)
> +			vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
>  
> -	vop2_post_config(crtc, false, crtc_state, old_crtc_state);
> +		vop2_post_config(crtc, false, crtc_state, old_crtc_state);
>  
> -	vop2_cfg_done(vp);
> +		vop2_cfg_done(vp);
> +	}
>  
>  	spin_lock_irq(&crtc->dev->event_lock);

[Severity: High]
As reported by Sashiko on v2 [1], how is crtc->state->event handled in
vop2_crtc_atomic_flush() when vop2_crtc_atomic_enable() fails and leaves
vp->enabled as false?

When vop2_crtc_atomic_enable() aborts on any error path, it returns before
calling drm_crtc_vblank_on(crtc). Later in the same commit tail,
drm_atomic_helper_commit_planes() still calls vop2_crtc_atomic_flush(), which
runs:

	spin_lock_irq(&crtc->dev->event_lock);

	if (crtc->state->event) {
		WARN_ON(drm_crtc_vblank_get(crtc));
		vp->event = crtc->state->event;
		crtc->state->event = NULL;
	}

	spin_unlock_irq(&crtc->dev->event_lock);

Because drm_crtc_vblank_on(crtc) was never called, drm_crtc_vblank_get(crtc)
fails with -EINVAL and triggers the WARN_ON(). The event is then moved into
vp->event, but because the video port is not running and vop2_cfg_done(vp)
was skipped, the frame start interrupt never fires to complete vp->event, and
vop2_crtc_atomic_disable() only checks crtc->state->event while skipping
teardown when !vp->enabled.

Does this leave commit->flip_done unsignaled (stalling subsequent commits on
this CRTC in drm_atomic_helper_wait_for_dependencies()) and leak vp->event if
another commit flushes before the CRTC is enabled, or cause an unbalanced
drm_crtc_vblank_put() in the interrupt handler if a later modeset succeeds?
When !vp->enabled, should vop2_crtc_atomic_flush() send crtc->state->event
immediately via drm_crtc_send_vblank_event() instead of queuing it in
vp->event?

[1] https://lore.kernel.org/r/20260706194935.AC7601F000E9@smtp.kernel.org

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261105-dw-hdmi-qp-yuv-v6-0-1bb63ef5766e@collabora.com?part=4

  reply	other threads:[~2026-11-05  1:20 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05  1:00 [PATCH v6 00/15] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP Cristian Ciocaltea
2026-11-05  1:00 ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 01/15] dt-bindings: display: vop2: Add missing reset properties Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 02/15] drm/rockchip: vop2: Fix resource leak on vop2_enable() error path Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 03/15] drm/rockchip: vop2: Disable core clocks before dropping runtime PM reference Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 11:43   ` Daniel Stone
2026-11-05 11:43     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 04/15] drm/rockchip: vop2: Balance state on atomic_enable() error paths Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:20   ` sashiko-bot [this message]
2026-11-05 12:24   ` Daniel Stone
2026-11-05 12:24     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 05/15] drm/rockchip: vop2: Avoid division by zero when computing max_dclk Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 06/15] drm/rockchip: vop2: Fix VOP2_MAX_DCLK_RATE overflow on 32-bit Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 07/15] drm/rockchip: vop2: Reset AXI and DCLK to improve robustness Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:20   ` sashiko-bot
2026-11-05  1:00 ` [PATCH v6 08/15] drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 12:18   ` Daniel Stone
2026-11-05 12:18     ` Daniel Stone
2026-11-05 12:56     ` Cristian Ciocaltea
2026-11-05 12:56       ` Cristian Ciocaltea
2026-11-05 14:33       ` Daniel Stone
2026-11-05 14:33         ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 09/15] drm/rockchip: vop2: Use TMDS character rate to select DCLK source Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 14:35   ` Daniel Stone
2026-11-05 14:35     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 10/15] drm/rockchip: vop2: Switch to enum vop_csc_format Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 11/15] drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable() Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05  1:00 ` [PATCH v6 12/15] drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check() Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 11:55   ` Daniel Stone
2026-11-05 11:55     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 13/15] drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 12:08   ` Daniel Stone
2026-11-05 12:08     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 14/15] drm/rockchip: dw_hdmi_qp: Enable YUV420 " Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 12:09   ` Daniel Stone
2026-11-05 12:09     ` Daniel Stone
2026-11-05  1:00 ` [PATCH v6 15/15] arm64: dts: rockchip: Add RK3588 VOP2 resets Cristian Ciocaltea
2026-11-05  1:00   ` Cristian Ciocaltea
2026-11-05 12:25 ` [PATCH v6 00/15] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP Daniel Stone
2026-11-05 12:25   ` Daniel Stone
2026-11-05 13:04   ` Cristian Ciocaltea
2026-11-05 13:04     ` Cristian Ciocaltea
2026-11-05 13:22     ` Heiko Stübner
2026-11-05 13:22       ` Heiko Stübner
2026-11-05 14:36       ` Daniel Stone
2026-11-05 14:36         ` Daniel Stone
2026-11-05 14:35     ` Daniel Stone
2026-11-05 14:35       ` Daniel Stone
2026-11-06 12:27 ` (subset) " Heiko Stuebner
2026-11-06 12:27   ` Heiko Stuebner
2026-11-06 12:28 ` Heiko Stuebner
2026-11-06 12:28   ` Heiko Stuebner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-198400@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=cristian.ciocaltea@collabora.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.