All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Hugo Sales" <hugo@hsal.es>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/amd/display: Hold the VRR vblank reference only on active CRTCs
Date: Sat, 31 Oct 2026 14:54:20 +0000	[thread overview]
Message-ID: <sashiko-outbox-192001@kernel.org> (raw)
In-Reply-To: <20261031143351.3222033-1-hugo@hsal.es>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] drm/amd/display: dc_exit_ips_for_hw_access() disables IPS on CRTC disable
--

commit 8e13aac5aafca2cc16730e98147592bfe9db266f
Author: Hugo Sales <hugo@hsal.es>

drm/amd/display: Hold the VRR vblank reference only on active CRTCs

This patch gates the VRR active state check in
amdgpu_dm_handle_vrr_transition() on the CRTC's base.active flag so that
disabling a CRTC drops the VRR vblank reference and enabling it takes the
reference again.

> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
> index 386ba88c57c6a..ee8a11f62a0d3 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
> @@ -414,8 +414,16 @@ void amdgpu_dm_handle_vrr_transition(struct amdgpu_display_manager *dm,
>  				     struct dm_crtc_state *new_state)
>  {
>  	struct amdgpu_device *adev = dm->adev;
> -	bool old_vrr_active = amdgpu_dm_crtc_vrr_active(old_state);
> -	bool new_vrr_active = amdgpu_dm_crtc_vrr_active(new_state);
> +	/*
> +	 * A disabled CRTC keeps its freesync state, but drm_crtc_vblank_get()
> +	 * fails there because vblank is off. Hold the reference only while
> +	 * the CRTC is active as well, which also covers resume, where the
> +	 * reset state lost track of the reference taken before suspend
> +	 */
> +	bool old_vrr_active = old_state->base.active &&
> +			      amdgpu_dm_crtc_vrr_active(old_state);
> +	bool new_vrr_active = new_state->base.active &&
> +			      amdgpu_dm_crtc_vrr_active(new_state);

[Severity: Medium]
Can gating new_vrr_active on new_state->base.active leave DC idle power
optimizations (IPS) disabled when disabling the last active CRTC in a
headless configuration while VRR was active?

In drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c,
amdgpu_dm_atomic_commit_tail() first calls amdgpu_dm_commit_streams(),
which disables vblank via manage_dm_interrupts(), flushes
dm->vblank_control_workqueue, commits the stream removal, and enables idle
optimizations for headless display-off:

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:amdgpu_dm_commit_streams() {
	...
	/* Allow idle optimization when vblank count is 0 for display off */
	if ((dm->active_vblank_irq_count == 0) && amdgpu_dm_is_headless(dm->adev))
		dc_allow_idle_optimizations(dm->dc, true);
}

Later in amdgpu_dm_atomic_commit_tail(), amdgpu_dm_handle_vrr_transition()
runs. When disabling a CRTC that had VRR_STATE_ACTIVE_VARIABLE,
old_vrr_active is true and new_vrr_active is now false, so execution enters
the old_vrr_active && !new_vrr_active branch:

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c:amdgpu_dm_handle_vrr_transition() {
	...
	} else if (old_vrr_active && !new_vrr_active) {
		...
		drm_crtc_vblank_put(new_state->base.crtc);
		...
		scoped_guard(mutex, &dm->dc_lock) {
			dc_exit_ips_for_hw_access(dm->dc);
			amdgpu_dm_psr_set_event(dm, new_state->stream, false,
				psr_event_vrr_transition, false);
			amdgpu_dm_replay_set_event(dm, new_state->stream, false,
				replay_event_vrr, false);
		}
	}
}

Because drm_crtc_vblank_off() already set vblank->inmodeset and holds a
vblank reference, drm_crtc_vblank_put() decrements vblank->refcount from 2
to 1 without scheduling vblank_control_work.

Then dc_exit_ips_for_hw_access(dm->dc) unconditionally calls
dc_allow_idle_optimizations(dm->dc, false), even though new_state->stream
is NULL when the CRTC is being disabled and both amdgpu_dm_psr_set_event()
and amdgpu_dm_replay_set_event() immediately return false at their !stream
checks without touching hardware.

Since new_state->stream is NULL, amdgpu_dm_commit_planes() is skipped, and
amdgpu_dm_idle_worker() breaks out of its loop upon seeing
!dc->idle_optimizations_allowed. Should the dc_lock block and
dc_exit_ips_for_hw_access() in that branch be skipped when
new_state->stream is NULL?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261031143351.3222033-1-hugo@hsal.es?part=1

           reply	other threads:[~2026-10-31 14:54 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <20261031143351.3222033-1-hugo@hsal.es>]

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-192001@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hugo@hsal.es \
    --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.