From: Sumit Gupta <sumitg@nvidia.com>
To: Christian Loehle <christian.loehle@arm.com>,
rafael@kernel.org, viresh.kumar@linaro.org,
pierre.gondois@arm.com, ionela.voinescu@arm.com,
zhenglifeng1@huawei.com, zhanjie9@hisilicon.com, lenb@kernel.org,
saket.dumbre@intel.co, ray.huang@amd.com,
mario.limonciello@amd.com, perry.yuan@amd.com,
kprateek.nayak@amd.com, linux-kernel@vger.kernel.org,
linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org,
acpica-devel@lists.linux.dev, linux-tegra@vger.kernel.org
Cc: treding@nvidia.com, jonathanh@nvidia.com, vsethi@nvidia.com,
ksitaraman@nvidia.com, sanjayc@nvidia.com, mochs@nvidia.com,
bbasu@nvidia.com, sumitg@nvidia.com
Subject: Re: [PATCH v3 1/4] cpufreq: CPPC: Keep the policy across CPU hotplug
Date: Wed, 29 Jul 2026 20:11:13 +0530 [thread overview]
Message-ID: <d8296b93-9bc2-49fc-b46b-d7dd37af2abd@nvidia.com> (raw)
In-Reply-To: <40d72385-0b3f-46e5-9f32-a27be3842d7c@arm.com>
On 27/07/26 18:57, Christian Loehle wrote:
> External email: Use caution opening links or attachments
>
>
> On 7/24/26 22:59, Sumit Gupta wrote:
>> Without online()/offline() callbacks, the cpufreq core fully tears
>> down a policy during exit() when its last online CPU is offlined, and
>> rebuilds it during init() when it comes back.
>>
>> Add lightweight online()/offline() callbacks so the core instead keeps
>> the policy live and reuses the driver's cpu_data across CPU hotplug.
>> This avoids re-reading the CPPC capabilities on every offline/online,
>> making CPU hotplug faster.
>>
>> From online(), re-enable CPPC, as the platform may have disabled it
>> while the CPU was offline. Since the policy is no longer rebuilt via
>> init(), online() also reprograms the CPPC performance controls
>> (desired/min/max).
>>
>> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
>> ---
>> drivers/cpufreq/cppc_cpufreq.c | 44 ++++++++++++++++++++++++++++++++++
>> 1 file changed, 44 insertions(+)
>>
>> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
>> index f6cea0c54dd9..6dc59f99d880 100644
>> --- a/drivers/cpufreq/cppc_cpufreq.c
>> +++ b/drivers/cpufreq/cppc_cpufreq.c
>> @@ -722,6 +722,48 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
>> return ret;
>> }
>>
>> +/*
>> + * With offline() defined, the cpufreq core keeps the policy alive when
>> + * a CPU is hotplugged out.
>> + */
>> +static int cppc_cpufreq_cpu_offline(struct cpufreq_policy *policy)
>> +{
>> + return 0;
>> +}
>> +
>> +/*
>> + * Re-enable CPPC when the policy's CPU comes back online, since the platform
>> + * may have disabled it while the CPU was offline.
>> + */
>> +static int cppc_cpufreq_cpu_online(struct cpufreq_policy *policy)
>> +{
>> + struct cppc_cpudata *cpu_data = policy->driver_data;
>> + unsigned int cpu = policy->cpu;
>> + int ret;
>> +
>> + ret = cppc_set_enable(cpu, true);
>> + if (ret && ret != -EOPNOTSUPP)
>> + pr_warn("Failed to re-enable CPPC for CPU%d (%d)\n", cpu, ret);
> What's the intention of continuing restoring CPPC register values here?
Yes, there is no benefit in continuing the restore when
cppc_set_enable() fails with anything other than -EOPNOTSUPP.
I will stop the restore at that point and return 0 with a warning,
since propagating the error would cause the core to tear down
the policy.
>> +
>> + /*
>> + * The platform may reset the controls while the CPU is offline, so
>> + * recompute min/max, clamp desired_perf into range, and reprogram them.
>> + */
>> + cppc_cpufreq_update_perf_limits(cpu_data, policy);
>> +
>> + cpu_data->perf_ctrls.desired_perf =
>> + clamp_t(u32, cpu_data->perf_ctrls.desired_perf,
>> + cpu_data->perf_ctrls.min_perf,
>> + cpu_data->perf_ctrls.max_perf);
>> +
>> + ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
>> + if (ret)
>> + pr_debug("Failed to reapply perf request on CPU%d (%d)\n",
>> + cpu, ret);
> I think cppc_set_perf() needs some prep first before using it on reset values.
> We assume that reset value may be Autonomous Mode on, right? So we must never
> write MIN>MAX and vice versa. I think we may just have to read and write
> the 'otherwise-offending' value first on reset.
You are right. cppc_set_perf() writes MIN before MAX, so restoring
a window whose MIN is above the reset MAX can briefly produce MIN > MAX
on registers not accessed through PCC. I will add a preparatory write
that raises MAX in that case, followed by the full restore:
----
/* min/max recomputed and desired_perf clamped, as posted */
cppc_get_perf(cpu, &cur);
if (cpu_data->perf_ctrls.min_perf > cur.max_perf) {
prep = cur; /* Rewrites DESIRED with its current value. */
prep.min_perf = 0; /* Zero leaves MIN unchanged. */
prep.max_perf = cpu_data->perf_ctrls.max_perf;
/* Raise MAX first. */
cppc_set_perf(cpu, &prep);
}
/* Then restore the full desired/min/max request. */
cppc_set_perf(cpu, &cpu_data->perf_ctrls);
----
The reverse transition does not need this extra write because the
existing MIN-before-MAX order writes the lower MIN first, so the window
only widens before MAX comes down.
Please let me know if you see any issue with this.
Thanks,
Sumit
....
next prev parent reply other threads:[~2026-07-29 14:41 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-24 21:59 [PATCH v3 0/4] cpufreq: CPPC: Preserve OSPM-set registers across hotplug and unload Sumit Gupta
2026-07-24 21:59 ` [PATCH v3 1/4] cpufreq: CPPC: Keep the policy across CPU hotplug Sumit Gupta
2026-07-27 13:27 ` Christian Loehle
2026-07-29 14:41 ` Sumit Gupta [this message]
2026-07-28 8:41 ` zhenglifeng (A)
2026-07-29 17:05 ` Sumit Gupta
2026-07-24 21:59 ` [PATCH v3 2/4] ACPI: CPPC: Make autonomous selection helpers take a u64 Sumit Gupta
2026-07-24 21:59 ` [PATCH v3 3/4] cpufreq: CPPC: Preserve OSPM-set registers across hotplug and unload Sumit Gupta
2026-07-27 13:15 ` Christian Loehle
2026-07-24 21:59 ` [PATCH v3 4/4] cpufreq: CPPC: Preserve OSPM-set registers across suspend/resume Sumit Gupta
2026-07-27 13:45 ` Christian Loehle
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=d8296b93-9bc2-49fc-b46b-d7dd37af2abd@nvidia.com \
--to=sumitg@nvidia.com \
--cc=acpica-devel@lists.linux.dev \
--cc=bbasu@nvidia.com \
--cc=christian.loehle@arm.com \
--cc=ionela.voinescu@arm.com \
--cc=jonathanh@nvidia.com \
--cc=kprateek.nayak@amd.com \
--cc=ksitaraman@nvidia.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=mochs@nvidia.com \
--cc=perry.yuan@amd.com \
--cc=pierre.gondois@arm.com \
--cc=rafael@kernel.org \
--cc=ray.huang@amd.com \
--cc=saket.dumbre@intel.co \
--cc=sanjayc@nvidia.com \
--cc=treding@nvidia.com \
--cc=viresh.kumar@linaro.org \
--cc=vsethi@nvidia.com \
--cc=zhanjie9@hisilicon.com \
--cc=zhenglifeng1@huawei.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