* [PATCH V2 1/5] cpufreq: acpi: Re-sync CPU boost state on system resume
2025-04-24 16:20 [PATCH V2 0/5] cpufreq: Boost related cleanups / fixes Viresh Kumar
@ 2025-04-24 16:20 ` Viresh Kumar
2025-04-25 16:30 ` Rafael J. Wysocki
2025-04-24 16:20 ` [PATCH V2 2/5] cpufreq: Don't unnecessarily call set_boost() Viresh Kumar
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2025-04-24 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, Lifeng Zheng
Cc: linux-pm, Vincent Guittot, Nicholas Chin, Rafael J. Wysocki,
linux-kernel
During CPU hotunplug events (such as those occurring during
suspend/resume cycles), platform firmware may modify the CPU boost
state.
If boost was disabled prior to CPU removal, it correctly remains
disabled upon re-plug. However, if firmware re-enables boost while the
CPU is offline, the CPU may return with boost enabled—even if it was
originally disabled—once it is hotplugged back in. This leads to
inconsistent behavior and violates user or kernel policy expectations.
To maintain consistency, ensure the boost state is re-synchronized with
the kernel policy when a CPU is hotplugged back in.
Note: This re-synchronization is not necessary during the initial call
to ->init() for a CPU, as the cpufreq core handles it via
cpufreq_online(). At that point, acpi_cpufreq_driver.boost_enabled is
initialized to the value returned by boost_state(0).
Fixes: 2b16c631832d ("cpufreq: ACPI: Remove set_boost in acpi_cpufreq_cpu_init()")
Reported-by: Nicholas Chin <nic.c3.14@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220013
Tested-by: Nicholas Chin <nic.c3.14@gmail.com>
Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/acpi-cpufreq.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 924314cdeebc..d26b610e4f24 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -909,8 +909,19 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
pr_warn(FW_WARN "P-state 0 is not max freq\n");
- if (acpi_cpufreq_driver.set_boost)
- policy->boost_supported = true;
+ if (acpi_cpufreq_driver.set_boost) {
+ if (policy->boost_supported) {
+ /*
+ * The firmware may have altered boost state while the
+ * CPU was offline (for example during a suspend-resume
+ * cycle).
+ */
+ if (policy->boost_enabled != boost_state(cpu))
+ set_boost(policy, policy->boost_enabled);
+ } else {
+ policy->boost_supported = true;
+ }
+ }
return result;
--
2.31.1.272.g89b43f80a514
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH V2 1/5] cpufreq: acpi: Re-sync CPU boost state on system resume
2025-04-24 16:20 ` [PATCH V2 1/5] cpufreq: acpi: Re-sync CPU boost state on system resume Viresh Kumar
@ 2025-04-25 16:30 ` Rafael J. Wysocki
0 siblings, 0 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2025-04-25 16:30 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rafael J. Wysocki, Lifeng Zheng, linux-pm, Vincent Guittot,
Nicholas Chin, Rafael J. Wysocki, linux-kernel
On Thu, Apr 24, 2025 at 6:20 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> During CPU hotunplug events (such as those occurring during
> suspend/resume cycles), platform firmware may modify the CPU boost
> state.
>
> If boost was disabled prior to CPU removal, it correctly remains
> disabled upon re-plug. However, if firmware re-enables boost while the
> CPU is offline, the CPU may return with boost enabled—even if it was
> originally disabled—once it is hotplugged back in. This leads to
> inconsistent behavior and violates user or kernel policy expectations.
>
> To maintain consistency, ensure the boost state is re-synchronized with
> the kernel policy when a CPU is hotplugged back in.
>
> Note: This re-synchronization is not necessary during the initial call
> to ->init() for a CPU, as the cpufreq core handles it via
> cpufreq_online(). At that point, acpi_cpufreq_driver.boost_enabled is
> initialized to the value returned by boost_state(0).
>
> Fixes: 2b16c631832d ("cpufreq: ACPI: Remove set_boost in acpi_cpufreq_cpu_init()")
> Reported-by: Nicholas Chin <nic.c3.14@gmail.com>
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220013
> Tested-by: Nicholas Chin <nic.c3.14@gmail.com>
> Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
I gather that this patch is for 6.15 and the rest of the series is for
6.16, so applied accordingly.
> ---
> drivers/cpufreq/acpi-cpufreq.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
> index 924314cdeebc..d26b610e4f24 100644
> --- a/drivers/cpufreq/acpi-cpufreq.c
> +++ b/drivers/cpufreq/acpi-cpufreq.c
> @@ -909,8 +909,19 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
> if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
> pr_warn(FW_WARN "P-state 0 is not max freq\n");
>
> - if (acpi_cpufreq_driver.set_boost)
> - policy->boost_supported = true;
> + if (acpi_cpufreq_driver.set_boost) {
> + if (policy->boost_supported) {
> + /*
> + * The firmware may have altered boost state while the
> + * CPU was offline (for example during a suspend-resume
> + * cycle).
> + */
> + if (policy->boost_enabled != boost_state(cpu))
> + set_boost(policy, policy->boost_enabled);
> + } else {
> + policy->boost_supported = true;
> + }
> + }
>
> return result;
>
> --
> 2.31.1.272.g89b43f80a514
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH V2 2/5] cpufreq: Don't unnecessarily call set_boost()
2025-04-24 16:20 [PATCH V2 0/5] cpufreq: Boost related cleanups / fixes Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 1/5] cpufreq: acpi: Re-sync CPU boost state on system resume Viresh Kumar
@ 2025-04-24 16:20 ` Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 3/5] cpufreq: Introduce policy_set_boost() Viresh Kumar
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2025-04-24 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar
Cc: linux-pm, Vincent Guittot, Lifeng Zheng, Nicholas Chin,
linux-kernel
The policy specific boost value may already be set correctly in
cpufreq_boost_trigger_state(), don't update it again unnecessarily.
Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3841c9da6cac..e31891c7b500 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2861,7 +2861,7 @@ static int cpufreq_boost_trigger_state(int state)
cpus_read_lock();
for_each_active_policy(policy) {
- if (!policy->boost_supported)
+ if (!policy->boost_supported || policy->boost_enabled == state)
continue;
policy->boost_enabled = state;
--
2.31.1.272.g89b43f80a514
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH V2 3/5] cpufreq: Introduce policy_set_boost()
2025-04-24 16:20 [PATCH V2 0/5] cpufreq: Boost related cleanups / fixes Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 1/5] cpufreq: acpi: Re-sync CPU boost state on system resume Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 2/5] cpufreq: Don't unnecessarily call set_boost() Viresh Kumar
@ 2025-04-24 16:20 ` Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 4/5] cpufreq: Preserve policy's boost state after resume Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 5/5] cpufreq: Force sync policy boost with global boost on sysfs update Viresh Kumar
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2025-04-24 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar
Cc: linux-pm, Vincent Guittot, Lifeng Zheng, Nicholas Chin,
linux-kernel
Introduce policy_set_boost() to update boost state of a cpufreq policy.
No intentional function change.
Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq.c | 49 +++++++++++++++++++++------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e31891c7b500..24745088403b 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -620,6 +620,22 @@ static ssize_t show_local_boost(struct cpufreq_policy *policy, char *buf)
return sysfs_emit(buf, "%d\n", policy->boost_enabled);
}
+static int policy_set_boost(struct cpufreq_policy *policy, bool enable)
+{
+ int ret;
+
+ if (policy->boost_enabled == enable)
+ return 0;
+
+ policy->boost_enabled = enable;
+
+ ret = cpufreq_driver->set_boost(policy, enable);
+ if (ret)
+ policy->boost_enabled = !policy->boost_enabled;
+
+ return ret;
+}
+
static ssize_t store_local_boost(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
@@ -635,21 +651,14 @@ static ssize_t store_local_boost(struct cpufreq_policy *policy,
if (!policy->boost_supported)
return -EINVAL;
- if (policy->boost_enabled == enable)
- return count;
-
- policy->boost_enabled = enable;
-
cpus_read_lock();
- ret = cpufreq_driver->set_boost(policy, enable);
+ ret = policy_set_boost(policy, enable);
cpus_read_unlock();
- if (ret) {
- policy->boost_enabled = !policy->boost_enabled;
- return ret;
- }
+ if (!ret)
+ return count;
- return count;
+ return ret;
}
static struct freq_attr local_boost = __ATTR(boost, 0644, show_local_boost, store_local_boost);
@@ -1618,15 +1627,12 @@ static int cpufreq_online(unsigned int cpu)
policy->cdev = of_cpufreq_cooling_register(policy);
/* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
- if (cpufreq_driver->set_boost && policy->boost_supported &&
- policy->boost_enabled != cpufreq_boost_enabled()) {
- policy->boost_enabled = cpufreq_boost_enabled();
- ret = cpufreq_driver->set_boost(policy, policy->boost_enabled);
+ if (cpufreq_driver->set_boost && policy->boost_supported) {
+ ret = policy_set_boost(policy, cpufreq_boost_enabled());
if (ret) {
/* If the set_boost fails, the online operation is not affected */
pr_info("%s: CPU%d: Cannot %s BOOST\n", __func__, policy->cpu,
- str_enable_disable(policy->boost_enabled));
- policy->boost_enabled = !policy->boost_enabled;
+ str_enable_disable(cpufreq_boost_enabled()));
}
}
@@ -2861,15 +2867,12 @@ static int cpufreq_boost_trigger_state(int state)
cpus_read_lock();
for_each_active_policy(policy) {
- if (!policy->boost_supported || policy->boost_enabled == state)
+ if (!policy->boost_supported)
continue;
- policy->boost_enabled = state;
- ret = cpufreq_driver->set_boost(policy, state);
- if (ret) {
- policy->boost_enabled = !policy->boost_enabled;
+ ret = policy_set_boost(policy, state);
+ if (ret)
goto err_reset_state;
- }
}
cpus_read_unlock();
--
2.31.1.272.g89b43f80a514
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH V2 4/5] cpufreq: Preserve policy's boost state after resume
2025-04-24 16:20 [PATCH V2 0/5] cpufreq: Boost related cleanups / fixes Viresh Kumar
` (2 preceding siblings ...)
2025-04-24 16:20 ` [PATCH V2 3/5] cpufreq: Introduce policy_set_boost() Viresh Kumar
@ 2025-04-24 16:20 ` Viresh Kumar
2025-04-24 16:20 ` [PATCH V2 5/5] cpufreq: Force sync policy boost with global boost on sysfs update Viresh Kumar
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2025-04-24 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar
Cc: linux-pm, Vincent Guittot, Lifeng Zheng, Nicholas Chin,
linux-kernel
If the global boost flag was enabled and policy boost flag was disabled
before a suspend resume cycle, cpufreq_online() will enable the policy
boost flag on resume.
While it is important for the policy boost flag to mirror the global
boost flag when a policy is first created, it should be avoided when the
policy is reinitialized (for example after a suspend resume cycle).
Though, if the global boost flag is disabled at this point of time, we
want to make sure policy boost flag is disabled too.
Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 24745088403b..0ad459bc8f84 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1626,8 +1626,13 @@ static int cpufreq_online(unsigned int cpu)
if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver))
policy->cdev = of_cpufreq_cooling_register(policy);
- /* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
- if (cpufreq_driver->set_boost && policy->boost_supported) {
+ /*
+ * Let the per-policy boost flag mirror the cpufreq_driver boost during
+ * initialization for a new policy. For an existing policy, maintain the
+ * previous boost value unless global boost is disabled.
+ */
+ if (cpufreq_driver->set_boost && policy->boost_supported &&
+ (new_policy || !cpufreq_boost_enabled())) {
ret = policy_set_boost(policy, cpufreq_boost_enabled());
if (ret) {
/* If the set_boost fails, the online operation is not affected */
--
2.31.1.272.g89b43f80a514
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH V2 5/5] cpufreq: Force sync policy boost with global boost on sysfs update
2025-04-24 16:20 [PATCH V2 0/5] cpufreq: Boost related cleanups / fixes Viresh Kumar
` (3 preceding siblings ...)
2025-04-24 16:20 ` [PATCH V2 4/5] cpufreq: Preserve policy's boost state after resume Viresh Kumar
@ 2025-04-24 16:20 ` Viresh Kumar
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2025-04-24 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar
Cc: linux-pm, Vincent Guittot, Lifeng Zheng, Nicholas Chin,
linux-kernel
If the global boost flag is enabled and policy boost flag is disabled, a
call to `cpufreq_boost_trigger_state(true)` must enable the policy's
boost state.
The current code misses that because of an optimization. Fix it.
Suggested-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0ad459bc8f84..4ac5d4fcfdd4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2863,8 +2863,10 @@ static int cpufreq_boost_trigger_state(int state)
unsigned long flags;
int ret = 0;
- if (cpufreq_driver->boost_enabled == state)
- return 0;
+ /*
+ * Don't compare 'cpufreq_driver->boost_enabled' with 'state' here to
+ * make sure all policies are in sync with global boost flag.
+ */
write_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver->boost_enabled = state;
--
2.31.1.272.g89b43f80a514
^ permalink raw reply related [flat|nested] 7+ messages in thread