All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Li,Rongqing" <lirongqing@baidu.com>
To: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Viresh Kumar <viresh.kumar@linaro.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: 答复: [外部邮件] Re: [PATCH v2 2/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in get_cur_freq_on_cpu()
Date: Wed, 19 Aug 2026 11:21:21 +0000	[thread overview]
Message-ID: <07a6b0029e3f40e6ba028be1fc4a7617@baidu.com> (raw)
In-Reply-To: <3b1d40a0-1cc4-4974-ae1e-db5097147e05@oss.qualcomm.com>



> -----邮件原件-----
> 发件人: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
> 发送时间: 2026年8月18日 22:02
> 收件人: Li,Rongqing <lirongqing@baidu.com>; Rafael J . Wysocki
> <rafael@kernel.org>; Viresh Kumar <viresh.kumar@linaro.org>;
> linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org
> 抄送: zhongqiu.han@oss.qualcomm.com
> 主题: [外部邮件] Re: [PATCH v2 2/2] cpufreq: acpi-cpufreq: fix P-state index
> mismatch in get_cur_freq_on_cpu()
> 
> On 8/13/2026 5:01 PM, lirongqing wrote:
> > From: Li RongQing <lirongqing@baidu.com>
> >
> > get_cur_freq_on_cpu() reads the cached frequency as
> > policy->freq_table[to_perf_data(data)->state], mixing two different
> > policy->index
> > spaces: perf->state indexes perf->states[], while policy->freq_table[]
> > is built with duplicate frequencies removed and stores the original
> > P-state index in freq_table[].driver_data.
> >
> > Once any _PSS entry has been skipped the two arrays no longer line up,
> > so the cached frequency used to detect a "BIOS changed frequency
> > behind our back" event could be taken from the wrong table slot.
> 
> A further consequence of this index-space mismatch should be that, depending
> on which entry is picked, the check either fails on every call for P-states whose
> freq_table index differs from their _PSS index, causing data->resume to force a
> redundant control-register rewrite on every ->target(), or silently passes when
> the wrong slot happens to hold the frequency the firmware actually moved the
> CPU to, causing
> acpi_cpufreq_target() to short-circuit and leave the CPU running at a frequency
> the core does not expect until a different P-state is requested.
> 
> >
> > Look up the freq_table entry whose driver_data matches perf->state
> > instead of indexing freq_table[] with perf->state directly.
> >
> > Fixes: 8cee1eed8e78 ("cpufreq: ACPI: Remove freq_table from
> > acpi_cpufreq_data")
> 
> The real Fixes tag should be e56a727b023d ("[CPUFREQ] Make acpi-cpufreq
> more robust against BIOS freq changes behind our back.")
> 
> > Reported-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
> > Signed-off-by: Li RongQing <lirongqing@baidu.com>
> > ---
> >   drivers/cpufreq/acpi-cpufreq.c | 9 ++++++++-
> >   1 file changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/cpufreq/acpi-cpufreq.c
> > b/drivers/cpufreq/acpi-cpufreq.c index 1abe9ab..61ede49c 100644
> > --- a/drivers/cpufreq/acpi-cpufreq.c
> > +++ b/drivers/cpufreq/acpi-cpufreq.c
> > @@ -353,6 +353,7 @@ static u32 get_cur_val(const struct cpumask *mask,
> > struct acpi_cpufreq_data *dat
> >
> >   static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
> >   {
> > +	struct cpufreq_frequency_table *pos;
> >   	struct acpi_cpufreq_data *data;
> >   	struct cpufreq_policy *policy;
> >   	unsigned int freq;
> > @@ -368,7 +369,13 @@ static unsigned int get_cur_freq_on_cpu(unsigned
> int cpu)
> >   	if (unlikely(!data || !policy->freq_table))
> >   		return 0;
> >
> > -	cached_freq = policy->freq_table[to_perf_data(data)->state].frequency;
> 
> How about:
> 	struct acpi_processor_performance *perf = to_perf_data(data);
> 	...
> 	cached_freq = perf->states[perf->state].core_frequency * 1000;
> 

Thanks, that's cleaner and I've adopted it in v3.

Using perf->state to index perf->states[] (its native index space) is exactly right: it avoids the freq_table[] index-space mismatch at the root, and perf->states[perf->state].core_frequency * 1000 is the same value that gets stored into freq_table[] at init time, so the freq != cached_freq resync check is unchanged.

It also removes a corner case in my earlier freq_table-walk version: if perf->state points at a P-state that was deduplicated out of freq_table[], the walk finds no match and leaves cached_freq at 0, misfiring the check. Indexing perf->states[] directly avoids that.

Will send as part of v3.

[Li,Rongqing] 


> get_cur_freq_on_cpu() is only called on ACPI_ADR_SPACE_FIXED_HARDWARE
> platforms, and on such platforms perf->state is only assigned in the following
> functions:
> 
> (1) acpi_cpufreq_target(): perf->state is then the index of the P-state
>      last written to the hardware.
> (2) acpi_cpufreq_fast_switch(): same as above (1).
> 
> (3) acpi_cpufreq_cpu_init(): this sets the initial value perf->state =
>      0. In cpufreq_online(), after .init() has been called, .get() - i.e.
>      get_cur_freq_on_cpu() - is called once.  The freq read at that point
>      may be a leftover value from the hardware, but whether or not
>      "if (freq != cached_freq)" holds, the only consequence is
>      data->resume = 1, and data->resume has already been initialised to 1
>      in .init() anyway.
> 
> 
> > +	cached_freq = 0;
> > +	cpufreq_for_each_entry(pos, policy->freq_table)
> > +		if (pos->driver_data == to_perf_data(data)->state) {
> > +			cached_freq = pos->frequency;
> > +			break;
> > +		}
> > +
> >   	freq = extract_freq(policy, get_cur_val(cpumask_of(cpu), data));
> >   	if (freq != cached_freq) {
> >   		/*
> 
> 
> --
> Thx and BRs,
> Zhongqiu Han

  reply	other threads:[~2026-08-19 11:23 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-13  9:01 [PATCH v2 0/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in freq lookups lirongqing
2026-08-13  9:01 ` [PATCH v2 1/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in extract_io() lirongqing
2026-08-17 13:33   ` Zhongqiu Han
2026-08-18  6:46     ` 答复: [外部邮件] " Li,Rongqing
2026-08-18  8:38       ` Zhongqiu Han
2026-08-13  9:01 ` [PATCH v2 2/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in get_cur_freq_on_cpu() lirongqing
2026-08-18 14:02   ` Zhongqiu Han
2026-08-19 11:21     ` Li,Rongqing [this message]
2026-08-17 12:45 ` [PATCH v2 0/2] cpufreq: acpi-cpufreq: fix P-state index mismatch in freq lookups Zhongqiu Han

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=07a6b0029e3f40e6ba028be1fc4a7617@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 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.