From: sashiko-bot@kernel.org
To: "Eduardo Diaz" <iamedu@gmail.com>
Cc: dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915/cdclk: Don't trust boot readout for per-pipe cdclk/voltage tracking
Date: Sun, 30 Aug 2026 16:33:04 +0000 [thread overview]
Message-ID: <20260830163305.0307B1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260830161703.11570-1-iamedu@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Zeroing `min_cdclk` and `min_voltage_level` during boot readout corrupts the global state tracking for inherited pipes, leading to FIFO underruns on partial commits.
- [High] The boot-time invalidation of cdclk/voltage tracking is fragile and gets silently undone during hardware sanitization, breaking the fix for the remaining active pipes.
- [Medium] Moving the early return in the CDCLK update paths forces unnecessary global state duplication and memory allocation on every page flip.
- [Low] The `old_min_cdclk` and `old_min_voltage_level` parameters are now ignored and immediately overwritten.
--
commit edef4e8a0b14b779ca2831158248f1bc907d372c
Author: Eduardo Diaz <iamedu@gmail.com>
drm/i915/cdclk: Don't trust boot readout for per-pipe cdclk/voltage tracking
This commit addresses a bug where cold boot corrupts the internal eDP panel
due to cdclk/voltage tracking assuming firmware-programmed state as its own.
It invalidates the tracking state during readout and forces the cdclk and
voltage update functions to skip early returns.
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index a53d887271778..209a2373d17aa 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -2981,11 +2981,14 @@ static int intel_cdclk_update_crtc_min_cdclk(struct intel_atomic_state *state,
> bool allow_cdclk_decrease = intel_any_crtc_needs_modeset(state);
> int ret;
>
> - if (new_min_cdclk == old_min_cdclk)
> - return 0;
> -
> - if (!allow_cdclk_decrease && new_min_cdclk < old_min_cdclk)
> - return 0;
> + /*
> + * old_min_cdclk comes from the previous crtc_state, which after
> + * boot-time readout reflects whatever firmware/GOP left running,
> + * not what this driver has programmed. For an inherited pipe it
> + * equals new_min_cdclk by construction (same mode, same formula),
> + * so an early return here would skip the recalculation that
> + * matters. Always continue on to the cdclk_state check below.
> + */
>
> cdclk_state = intel_atomic_get_cdclk_state(state);
> if (IS_ERR(cdclk_state))
[Severity: Medium]
Moving this early return causes the state duplication and memory allocations
in intel_atomic_get_cdclk_state() to occur unconditionally on every commit,
including every page flip. Does this introduce a performance regression or
latency spike in this hot path?
[Severity: Low]
Additionally, since the old_min_cdclk value passed into the function is now
overwritten right after intel_atomic_get_cdclk_state() returns:
old_min_cdclk = cdclk_state->min_cdclk[crtc->pipe];
Does this make the old_min_cdclk parameter passed by the caller dead code
that is never actually read?
[ ... ]
> @@ -3026,12 +3029,10 @@ static int intel_cdclk_update_crtc_min_voltage_level(struct intel_atomic_state *
> bool allow_voltage_level_decrease = intel_any_crtc_needs_modeset(state);
> int ret;
>
> - if (new_min_voltage_level == old_min_voltage_level)
> - return 0;
> -
> - if (!allow_voltage_level_decrease &&
> - new_min_voltage_level < old_min_voltage_level)
> - return 0;
> + /*
> + * old_min_voltage_level is unreliable for the same reason; see
> + * intel_cdclk_update_crtc_min_cdclk().
> + */
>
> cdclk_state = intel_atomic_get_cdclk_state(state);
> if (IS_ERR(cdclk_state))
[Severity: Low]
Similarly to old_min_cdclk, is the old_min_voltage_level parameter now ignored
and overwritten before it is ever used?
[ ... ]
> @@ -3705,6 +3706,28 @@ void intel_cdclk_update_hw_state(struct intel_display *display)
> cdclk_state->dbuf_bw_min_cdclk = intel_dbuf_bw_min_cdclk(display, dbuf_bw_state);
> }
>
> +/*
> + * intel_cdclk_update_hw_state() seeds min_cdclk[]/min_voltage_level[]
> + * from readout's crtc_state, i.e. from whatever firmware/GOP left
> + * running, not from anything this driver has programmed. A pipe's
> + * first real modeset usually targets the same native mode, so the
> + * freshly computed value matches this seeded baseline and
> + * intel_cdclk_update_crtc_min_cdclk()/_min_voltage_level() conclude
> + * nothing changed, skipping the recalculation that matters. Call
> + * this after readout so the first real commit sees a difference.
> + */
> +void intel_cdclk_invalidate_min_tracking(struct intel_display *display)
> +{
> + struct intel_cdclk_state *cdclk_state =
> + to_intel_cdclk_state(display->cdclk.obj.state);
> + enum pipe pipe;
> +
> + for_each_pipe(display, pipe) {
> + cdclk_state->min_cdclk[pipe] = 0;
> + cdclk_state->min_voltage_level[pipe] = 0;
> + }
> +}
[Severity: High]
Does zeroing min_cdclk for all pipes corrupt the state for inherited pipes
that are not included in the first atomic commit?
If the OS performs a partial commit (e.g., a cursor update on a single pipe)
on a multi-display setup, intel_cdclk_update_crtc_min_cdclk() will only
update the tracking for the pipe in the commit.
Because intel_compute_min_cdclk() takes the maximum of all pipes' requirements,
will the untouched active pipes with 0 tracked requirement be starved of their
necessary clock speed, leading to a FIFO underrun?
[Severity: High]
Can this boot-time invalidation be silently undone during hardware sanitization?
If a CRTC requires sanitization during boot, intel_crtc_disable_noatomic()
calls intel_cdclk_crtc_disable_noatomic(), which in turn calls
intel_cdclk_update_hw_state().
intel_cdclk_update_hw_state() loops over all pipes and does:
cdclk_state->min_cdclk[pipe] = crtc_state->min_cdclk;
Since crtc_state->min_cdclk still contains the readout value, does this
re-seed the tracking values for the remaining active pipes, circumventing
the fix entirely?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260830161703.11570-1-iamedu@gmail.com?part=1
next prev parent reply other threads:[~2026-08-30 16:33 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-30 16:17 [PATCH] drm/i915/cdclk: Don't trust boot readout for per-pipe cdclk/voltage tracking Eduardo Diaz
2026-08-30 16:33 ` sashiko-bot [this message]
2026-08-31 7:39 ` Jani Nikula
2026-08-31 14:52 ` Eduardo Díaz
2026-09-01 23:48 ` Eduardo Díaz
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=20260830163305.0307B1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=iamedu@gmail.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox