* FAILED: patch "[PATCH] PM: EM: Fix late boot with holes in CPU topology" failed to apply to 6.12-stable tree
@ 2025-10-16 12:51 gregkh
2025-10-21 19:22 ` [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity() Sasha Levin
0 siblings, 1 reply; 5+ messages in thread
From: gregkh @ 2025-10-16 12:51 UTC (permalink / raw)
To: christian.loehle, kenneth.crudup, rafael.j.wysocki, stable; +Cc: stable
The patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 1ebe8f7e782523e62cd1fa8237f7afba5d1dae83
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2025101616-gigahertz-profane-b22c@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1ebe8f7e782523e62cd1fa8237f7afba5d1dae83 Mon Sep 17 00:00:00 2001
From: Christian Loehle <christian.loehle@arm.com>
Date: Sun, 31 Aug 2025 22:43:57 +0100
Subject: [PATCH] PM: EM: Fix late boot with holes in CPU topology
Commit e3f1164fc9ee ("PM: EM: Support late CPUs booting and capacity
adjustment") added a mechanism to handle CPUs that come up late by
retrying when any of the `cpufreq_cpu_get()` call fails.
However, if there are holes in the CPU topology (offline CPUs, e.g.
nosmt), the first missing CPU causes the loop to break, preventing
subsequent online CPUs from being updated.
Instead of aborting on the first missing CPU policy, loop through all
and retry if any were missing.
Fixes: e3f1164fc9ee ("PM: EM: Support late CPUs booting and capacity adjustment")
Suggested-by: Kenneth Crudup <kenneth.crudup@gmail.com>
Reported-by: Kenneth Crudup <kenneth.crudup@gmail.com>
Link: https://lore.kernel.org/linux-pm/40212796-734c-4140-8a85-854f72b8144d@panix.com/
Cc: 6.9+ <stable@vger.kernel.org> # 6.9+
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Link: https://patch.msgid.link/20250831214357.2020076-1-christian.loehle@arm.com
[ rjw: Drop the new pr_debug() message which is not very useful ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 8df55397414a..5f17d2e8e954 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -799,7 +799,7 @@ void em_adjust_cpu_capacity(unsigned int cpu)
static void em_check_capacity_update(void)
{
cpumask_var_t cpu_done_mask;
- int cpu;
+ int cpu, failed_cpus = 0;
if (!zalloc_cpumask_var(&cpu_done_mask, GFP_KERNEL)) {
pr_warn("no free memory\n");
@@ -817,10 +817,8 @@ static void em_check_capacity_update(void)
policy = cpufreq_cpu_get(cpu);
if (!policy) {
- pr_debug("Accessing cpu%d policy failed\n", cpu);
- schedule_delayed_work(&em_update_work,
- msecs_to_jiffies(1000));
- break;
+ failed_cpus++;
+ continue;
}
cpufreq_cpu_put(policy);
@@ -835,6 +833,9 @@ static void em_check_capacity_update(void)
em_adjust_new_capacity(cpu, dev, pd);
}
+ if (failed_cpus)
+ schedule_delayed_work(&em_update_work, msecs_to_jiffies(1000));
+
free_cpumask_var(cpu_done_mask);
}
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity()
2025-10-16 12:51 FAILED: patch "[PATCH] PM: EM: Fix late boot with holes in CPU topology" failed to apply to 6.12-stable tree gregkh
@ 2025-10-21 19:22 ` Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 2/4] PM: EM: Slightly reduce em_check_capacity_update() overhead Sasha Levin
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Sasha Levin @ 2025-10-21 19:22 UTC (permalink / raw)
To: stable; +Cc: Rafael J. Wysocki, Lukasz Luba, Sasha Levin
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
[ Upstream commit 5fad775d432c6c9158ea12e7e00d8922ef8d3dfc ]
The max_cap parameter is never used in em_adjust_new_capacity(), so
drop it.
No functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://patch.msgid.link/2369979.ElGaqSPkdT@rjwysocki.net
Stable-dep-of: 1ebe8f7e7825 ("PM: EM: Fix late boot with holes in CPU topology")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/power/energy_model.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 1c9fe741fe6d5..8ee72c6c1daf3 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -723,8 +723,7 @@ static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
* are correctly calculated.
*/
static void em_adjust_new_capacity(struct device *dev,
- struct em_perf_domain *pd,
- u64 max_cap)
+ struct em_perf_domain *pd)
{
struct em_perf_table *em_table;
@@ -795,7 +794,7 @@ static void em_check_capacity_update(void)
cpu, cpu_capacity, em_max_perf);
dev = get_cpu_device(cpu);
- em_adjust_new_capacity(dev, pd, cpu_capacity);
+ em_adjust_new_capacity(dev, pd);
}
free_cpumask_var(cpu_done_mask);
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.12.y 2/4] PM: EM: Slightly reduce em_check_capacity_update() overhead
2025-10-21 19:22 ` [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity() Sasha Levin
@ 2025-10-21 19:22 ` Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 3/4] PM: EM: Move CPU capacity check to em_adjust_new_capacity() Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 4/4] PM: EM: Fix late boot with holes in CPU topology Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2025-10-21 19:22 UTC (permalink / raw)
To: stable; +Cc: Rafael J. Wysocki, Lukasz Luba, Sasha Levin
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
[ Upstream commit a8e62726ac0dd7b610c87ba1a938a5a9091c34df ]
Every iteration of the loop over all possible CPUs in
em_check_capacity_update() causes get_cpu_device() to be called twice
for the same CPU, once indirectly via em_cpu_get() and once directly.
Get rid of the indirect get_cpu_device() call by moving the direct
invocation of it earlier and using em_pd_get() instead of em_cpu_get()
to get a pd pointer for the dev one returned by it.
This also exposes the fact that dev is needed to get a pd, so the code
becomes somewhat easier to follow after it.
No functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://patch.msgid.link/1925950.tdWV9SEqCh@rjwysocki.net
Stable-dep-of: 1ebe8f7e7825 ("PM: EM: Fix late boot with holes in CPU topology")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/power/energy_model.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 8ee72c6c1daf3..a035b030ff734 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -769,7 +769,8 @@ static void em_check_capacity_update(void)
}
cpufreq_cpu_put(policy);
- pd = em_cpu_get(cpu);
+ dev = get_cpu_device(cpu);
+ pd = em_pd_get(dev);
if (!pd || em_is_artificial(pd))
continue;
@@ -793,7 +794,6 @@ static void em_check_capacity_update(void)
pr_debug("updating cpu%d cpu_cap=%lu old capacity=%lu\n",
cpu, cpu_capacity, em_max_perf);
- dev = get_cpu_device(cpu);
em_adjust_new_capacity(dev, pd);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.12.y 3/4] PM: EM: Move CPU capacity check to em_adjust_new_capacity()
2025-10-21 19:22 ` [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity() Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 2/4] PM: EM: Slightly reduce em_check_capacity_update() overhead Sasha Levin
@ 2025-10-21 19:22 ` Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 4/4] PM: EM: Fix late boot with holes in CPU topology Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2025-10-21 19:22 UTC (permalink / raw)
To: stable
Cc: Rafael J. Wysocki, Lukasz Luba, Christian Loehle,
Dietmar Eggemann, Sasha Levin
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
[ Upstream commit 3e3ba654d3097e0031f2add215b12ff81c23814e ]
Move the check of the CPU capacity currently stored in the energy model
against the arch_scale_cpu_capacity() value to em_adjust_new_capacity()
so it will be done regardless of where the latter is called from.
This will be useful when a new em_adjust_new_capacity() caller is added
subsequently.
While at it, move the pd local variable declaration in
em_check_capacity_update() into the loop in which it is used.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Tested-by: Christian Loehle <christian.loehle@arm.com>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Link: https://patch.msgid.link/7810787.EvYhyI6sBW@rjwysocki.net
Stable-dep-of: 1ebe8f7e7825 ("PM: EM: Fix late boot with holes in CPU topology")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/power/energy_model.c | 40 ++++++++++++++++---------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index a035b030ff734..2ef0a7d9d8405 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -722,10 +722,24 @@ static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
* Adjustment of CPU performance values after boot, when all CPUs capacites
* are correctly calculated.
*/
-static void em_adjust_new_capacity(struct device *dev,
+static void em_adjust_new_capacity(unsigned int cpu, struct device *dev,
struct em_perf_domain *pd)
{
+ unsigned long cpu_capacity = arch_scale_cpu_capacity(cpu);
struct em_perf_table *em_table;
+ struct em_perf_state *table;
+ unsigned long em_max_perf;
+
+ rcu_read_lock();
+ table = em_perf_state_from_pd(pd);
+ em_max_perf = table[pd->nr_perf_states - 1].performance;
+ rcu_read_unlock();
+
+ if (em_max_perf == cpu_capacity)
+ return;
+
+ pr_debug("updating cpu%d cpu_cap=%lu old capacity=%lu\n", cpu,
+ cpu_capacity, em_max_perf);
em_table = em_table_dup(pd);
if (!em_table) {
@@ -741,9 +755,6 @@ static void em_adjust_new_capacity(struct device *dev,
static void em_check_capacity_update(void)
{
cpumask_var_t cpu_done_mask;
- struct em_perf_state *table;
- struct em_perf_domain *pd;
- unsigned long cpu_capacity;
int cpu;
if (!zalloc_cpumask_var(&cpu_done_mask, GFP_KERNEL)) {
@@ -754,7 +765,7 @@ static void em_check_capacity_update(void)
/* Check if CPUs capacity has changed than update EM */
for_each_possible_cpu(cpu) {
struct cpufreq_policy *policy;
- unsigned long em_max_perf;
+ struct em_perf_domain *pd;
struct device *dev;
if (cpumask_test_cpu(cpu, cpu_done_mask))
@@ -777,24 +788,7 @@ static void em_check_capacity_update(void)
cpumask_or(cpu_done_mask, cpu_done_mask,
em_span_cpus(pd));
- cpu_capacity = arch_scale_cpu_capacity(cpu);
-
- rcu_read_lock();
- table = em_perf_state_from_pd(pd);
- em_max_perf = table[pd->nr_perf_states - 1].performance;
- rcu_read_unlock();
-
- /*
- * Check if the CPU capacity has been adjusted during boot
- * and trigger the update for new performance values.
- */
- if (em_max_perf == cpu_capacity)
- continue;
-
- pr_debug("updating cpu%d cpu_cap=%lu old capacity=%lu\n",
- cpu, cpu_capacity, em_max_perf);
-
- em_adjust_new_capacity(dev, pd);
+ em_adjust_new_capacity(cpu, dev, pd);
}
free_cpumask_var(cpu_done_mask);
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.12.y 4/4] PM: EM: Fix late boot with holes in CPU topology
2025-10-21 19:22 ` [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity() Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 2/4] PM: EM: Slightly reduce em_check_capacity_update() overhead Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 3/4] PM: EM: Move CPU capacity check to em_adjust_new_capacity() Sasha Levin
@ 2025-10-21 19:22 ` Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2025-10-21 19:22 UTC (permalink / raw)
To: stable; +Cc: Christian Loehle, Kenneth Crudup, Rafael J. Wysocki, Sasha Levin
From: Christian Loehle <christian.loehle@arm.com>
[ Upstream commit 1ebe8f7e782523e62cd1fa8237f7afba5d1dae83 ]
Commit e3f1164fc9ee ("PM: EM: Support late CPUs booting and capacity
adjustment") added a mechanism to handle CPUs that come up late by
retrying when any of the `cpufreq_cpu_get()` call fails.
However, if there are holes in the CPU topology (offline CPUs, e.g.
nosmt), the first missing CPU causes the loop to break, preventing
subsequent online CPUs from being updated.
Instead of aborting on the first missing CPU policy, loop through all
and retry if any were missing.
Fixes: e3f1164fc9ee ("PM: EM: Support late CPUs booting and capacity adjustment")
Suggested-by: Kenneth Crudup <kenneth.crudup@gmail.com>
Reported-by: Kenneth Crudup <kenneth.crudup@gmail.com>
Link: https://lore.kernel.org/linux-pm/40212796-734c-4140-8a85-854f72b8144d@panix.com/
Cc: 6.9+ <stable@vger.kernel.org> # 6.9+
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Link: https://patch.msgid.link/20250831214357.2020076-1-christian.loehle@arm.com
[ rjw: Drop the new pr_debug() message which is not very useful ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/power/energy_model.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 2ef0a7d9d8405..d839b564522f6 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -755,7 +755,7 @@ static void em_adjust_new_capacity(unsigned int cpu, struct device *dev,
static void em_check_capacity_update(void)
{
cpumask_var_t cpu_done_mask;
- int cpu;
+ int cpu, failed_cpus = 0;
if (!zalloc_cpumask_var(&cpu_done_mask, GFP_KERNEL)) {
pr_warn("no free memory\n");
@@ -773,10 +773,8 @@ static void em_check_capacity_update(void)
policy = cpufreq_cpu_get(cpu);
if (!policy) {
- pr_debug("Accessing cpu%d policy failed\n", cpu);
- schedule_delayed_work(&em_update_work,
- msecs_to_jiffies(1000));
- break;
+ failed_cpus++;
+ continue;
}
cpufreq_cpu_put(policy);
@@ -791,6 +789,9 @@ static void em_check_capacity_update(void)
em_adjust_new_capacity(cpu, dev, pd);
}
+ if (failed_cpus)
+ schedule_delayed_work(&em_update_work, msecs_to_jiffies(1000));
+
free_cpumask_var(cpu_done_mask);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-10-21 19:22 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-16 12:51 FAILED: patch "[PATCH] PM: EM: Fix late boot with holes in CPU topology" failed to apply to 6.12-stable tree gregkh
2025-10-21 19:22 ` [PATCH 6.12.y 1/4] PM: EM: Drop unused parameter from em_adjust_new_capacity() Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 2/4] PM: EM: Slightly reduce em_check_capacity_update() overhead Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 3/4] PM: EM: Move CPU capacity check to em_adjust_new_capacity() Sasha Levin
2025-10-21 19:22 ` [PATCH 6.12.y 4/4] PM: EM: Fix late boot with holes in CPU topology Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox