From: lirongqing <lirongqing@baidu.com>
To: "Rafael J . Wysocki" <rafael@kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
<linux-pm@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <zhongqiu.han@oss.qualcomm.com>, Li RongQing <lirongqing@baidu.com>
Subject: [PATCH v5 2/2] cpufreq: acpi-cpufreq: don't mask firmware P-state changes
Date: Sat, 7 Nov 2026 02:40:08 +0800 [thread overview]
Message-ID: <20261106184008.1728-3-lirongqing@baidu.com> (raw)
In-Reply-To: <20261106184008.1728-1-lirongqing@baidu.com>
From: Li RongQing <lirongqing@baidu.com>
get_cur_freq_on_cpu() detects a firmware frequency change behind the
OS's back by comparing the frequency decoded from the hardware with the
frequency cached by the cpufreq core. The previous patch fixes the
cached side of that comparison; this patch fixes the decoded side.
policy->freq_table is built by filtering out _PSS entries that are not
lower in frequency than the previous one, so firmware may autonomously
switch the CPU to one of the filtered-out P-states. The status of such
a P-state matches no freq_table entry, and extract_msr() then falls
back to freq_table[0].frequency, i.e. the highest frequency, instead of
reporting that the status is unknown.
As a result the comparison is defeated exactly when the OS is already
at the P-state corresponding to freq_table[0], which is particularly likely
under the performance governor: freq equals cached_freq, data->resume is
left clear, and the next ->target() call short-circuits without
rewriting the control register, leaving the CPU at the firmware-selected
P-state. Fixing the index mismatch alone therefore does not make the
detection work in that case.
Return 0 from extract_msr() when the status cannot be matched so that
the fallback no longer hides the firmware change, and treat a zero
result as a firmware frequency change in get_cur_freq_on_cpu(). Keep
returning the cached frequency to the cpufreq core in that case: a zero
return value there would be indistinguishable from a read failure and
would feed 0 into the cpufreq statistics. This also covers the
ACPI_ADR_SPACE_SYSTEM_IO path, where extract_io() already returns 0 for
an unmatched status.
check_freqs() is unaffected: it compares against a frequency taken from
freq_table, which is never 0, so an unknown status keeps the
verification loop from declaring success.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260910111329.2220-1-lirongqing@baidu.com
Fixes: e56a727b023d ("[CPUFREQ] Make acpi-cpufreq more robust against BIOS freq changes behind our back.")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/cpufreq/acpi-cpufreq.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 2d7d147..1e7dc1c 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -225,7 +225,7 @@ static unsigned extract_msr(struct cpufreq_policy *policy, u32 msr)
cpufreq_for_each_entry(pos, policy->freq_table)
if (msr == perf->states[pos->driver_data].status)
return pos->frequency;
- return policy->freq_table[0].frequency;
+ return 0;
}
static unsigned extract_freq(struct cpufreq_policy *policy, u32 val)
@@ -373,12 +373,14 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
cached_freq = perf->states[perf->state].core_frequency * 1000;
freq = extract_freq(policy, get_cur_val(cpumask_of(cpu), data));
- if (freq != cached_freq) {
+ if (!freq || freq != cached_freq) {
/*
* The dreaded BIOS frequency change behind our back.
* Force set the frequency on next target call.
*/
data->resume = 1;
+ if (!freq)
+ freq = cached_freq;
}
pr_debug("cur freq = %u\n", freq);
--
2.9.4
next prev parent reply other threads:[~2026-11-06 18:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 18:40 [PATCH v5 0/2] cpufreq: acpi-cpufreq: fix P-state index mismatch between perf->states[] and freq_table[] lirongqing
2026-11-06 18:40 ` [PATCH v5 1/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in get_cur_freq_on_cpu() lirongqing
2026-11-06 18:40 ` lirongqing [this message]
2026-11-10 20:01 ` [PATCH v5 0/2] cpufreq: acpi-cpufreq: fix P-state index mismatch between perf->states[] and freq_table[] Rafael J. Wysocki (Intel)
2026-11-12 2:15 ` 答复: [外部邮件] " Li,Rongqing
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=20261106184008.1728-3-lirongqing@baidu.com \
--to=lirongqing@baidu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=viresh.kumar@linaro.org \
--cc=zhongqiu.han@oss.qualcomm.com \
/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
all inboxes | Powered by JetHome®