* [PATCH v6 0/3] cpufreq: cppc: Handle Highest Performance changes at runtime
@ 2026-11-11 8:50 Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 1/3] cpufreq: cppc: Add update_limits support for Highest Performance changes Xueqin Luo
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Xueqin Luo @ 2026-11-11 8:50 UTC (permalink / raw)
To: rafael, viresh.kumar, sudeep.holla
Cc: zhanjie9, christian.loehle, zhenglifeng1, sumitg, lenb,
maciej.wieczor-retman, pawel.chmielewski, gregkh, dakr, johan,
ionela.voinescu, pierre.gondois, linux-pm, linux-acpi,
linux-kernel, acpica-devel, driver-core, Xueqin Luo
Hi Rafael, Pierre, Christian, Jie,
This series adds support for handling ACPI CPPC Highest Performance
register changes at runtime, triggered by Notify(0x85) on a processor
device. When the platform changes the Highest Performance value, the
OSPM must re-evaluate the cached capability and propagate the change
to the cpufreq policy, the scheduler's CPU capacity model, and the
frequency invariance engine.
Concrete use cases discussed during review of the previous versions:
- A processor can age over time and its core frequency degrades. It
is good if platforms can make OSPM and userspace aware of this
(Jie, Christian).
- Platform operating mode changes between "performance" and
"powersave" (longer battery life) when the top-most OPP is a
high-cost one (Rafael).
The mode-switch use case can also move Highest Performance back up,
e.g. when switching from powersave back to performance. update_limits
therefore accepts changes in both directions, capped at the Highest
Performance probed at policy init, as proposed by Christian: any
value above the first probe is ignored, since it would allow boost
support to appear after policy init, which the cpufreq core cannot
handle today (the boost QoS request is only created at policy init).
A policy that started without boost cannot gain it at runtime;
supporting that would need runtime QoS request creation in the core
and is left for later.
v5 -> v6:
- Cap runtime Highest Performance changes at the value probed at
policy init (Christian): any value above the first probe is
ignored, since it would allow boost support to appear after policy
init, which the cpufreq core cannot handle today (the boost QoS
request is only created at policy init). Within that bound both
decreases and increases are accepted, so a platform switching back
to a performance mode restores the previous Highest Performance
(Rafael's mode-switch use case).
- Refresh the topology capacity for every CPU of the policy
(policy->related_cpus, covering offline CPUs of the domain as
well) instead of only policy->cpu, so a shared-policy Notify(0x85)
targeting any CPU of the policy refreshes the whole domain at
once (Christian).
- Trim the internal helper comments (cppc_cpufreq_sync_boost_limits(),
cppc_cpufreq_set_autonomous_perf()) down to the essential notes,
drop the debug-only value dump, and report boost QoS sync failures
through pr_err (Jie).
- Ignore values that would drop Highest Performance below Nominal:
they violate the CPPC invariant and cannot be handled cleanly, so
the special-casing for them is gone; such
values are now warned about (Jie).
topology_update_cpu_capacity() rejects such values as well, to
match the boot-time validation.
- Return early from cppc_cpufreq_update_limits() when the policy is
inactive: a concurrent CPU offline may have freed the driver data
after cpufreq_update_limits() acquired the policy reference.
Note: proposed spec extensions would allow nominal_perf to change
at runtime [1] and introduce a highest_freq value; neither is
handled here.
[1] https://lore.kernel.org/all/20260430142430.755437-3-sumitg@nvidia.com/
The series is split into three patches:
Patch 1: Core update_limits callback with boost QoS handling;
runtime changes capped at the boot-probed value.
Patch 2: Refactor autonomous perf bounds into a reusable helper
and wire it into update_limits with error logging.
Patch 3: Topology subsystem runtime capacity updates with
validation, early-return optimization, and concurrent-safe
normalization for all CPUs of the policy.
The v5 series was tested on an arm64 8-core big.LITTLE system with runtime
highest_perf changes injected through a debugfs hook that exercises
the same code path as ACPI Notify(0x85), including values above
1024 and full capacity re-normalization (see the v5 discussion for
the measured capacities).
Xueqin Luo (3):
cpufreq: cppc: Add update_limits support for Highest Performance
changes
cpufreq: cppc: Refactor autonomous perf bounds into helper
arch_topology: Add topology_update_cpu_capacity() for runtime updates
drivers/base/arch_topology.c | 77 ++++++++++++++++
drivers/cpufreq/cppc_cpufreq.c | 157 ++++++++++++++++++++++++++++++---
include/acpi/cppc_acpi.h | 1 +
include/linux/arch_topology.h | 13 +++
4 files changed, 235 insertions(+), 13 deletions(-)
Cc: Ionela Voinescu <ionela.voinescu@arm.com>
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v6 1/3] cpufreq: cppc: Add update_limits support for Highest Performance changes
2026-11-11 8:50 [PATCH v6 0/3] cpufreq: cppc: Handle Highest Performance changes at runtime Xueqin Luo
@ 2026-11-11 8:50 ` Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 2/3] cpufreq: cppc: Refactor autonomous perf bounds into helper Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates Xueqin Luo
2 siblings, 0 replies; 5+ messages in thread
From: Xueqin Luo @ 2026-11-11 8:50 UTC (permalink / raw)
To: rafael, viresh.kumar, sudeep.holla
Cc: zhanjie9, christian.loehle, zhenglifeng1, sumitg, lenb,
maciej.wieczor-retman, pawel.chmielewski, gregkh, dakr, johan,
ionela.voinescu, pierre.gondois, linux-pm, linux-acpi,
linux-kernel, acpica-devel, driver-core, Xueqin Luo
ACPI CPPC specification requires OSPM to re-evaluate the Highest
Performance register when Notify(0x85) is received for a processor
device.
Implement cppc_cpufreq_update_limits() to refresh the cached
highest_perf capability through cppc_get_highest_perf() and update
policy->cpuinfo.max_freq from Highest Performance. Use
refresh_frequency_limits() so policy->max follows the standard
cpufreq_set_policy() path.
Cap runtime changes at the Highest Performance probed at policy
init: any value above it is ignored, as it would allow boost support
to appear after policy init, which the cpufreq core cannot handle
because the boost QoS request is only created at policy init. Within
that bound both decreases and increases are accepted, e.g. a
platform switching back to a performance mode restores the previous
value. A policy initialized without boost cannot gain it at runtime
without core support for creating the QoS request later. Values
that would drop Highest Performance below Nominal are ignored too:
they violate the CPPC invariant and handling them would require
special-casing throughout the driver.
cpuinfo.max_freq always tracks Highest Performance. When boost is
disabled but still supported, constrain policy->max by updating the
existing boost_freq_req (created in cpufreq_policy_init_qos) to
nominal, instead of hiding the hardware maximum in cpuinfo.
Signed-off-by: Xueqin Luo <luoxueqin@kylinos.cn>
---
drivers/cpufreq/cppc_cpufreq.c | 100 +++++++++++++++++++++++++++++++++
include/acpi/cppc_acpi.h | 1 +
2 files changed, 101 insertions(+)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 957fa7775260..3bca30f5c0d5 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -639,6 +639,8 @@ static struct cppc_cpudata *cppc_cpufreq_get_cpu_data(unsigned int cpu)
goto free_mask;
}
+ cpu_data->init_highest_perf = cpu_data->perf_caps.highest_perf;
+
ret = cppc_get_perf(cpu, &cpu_data->perf_ctrls);
if (ret) {
pr_debug("Err reading CPU%d perf ctrls: ret:%d\n", cpu, ret);
@@ -866,6 +868,103 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
return 0;
}
+/*
+ * Boost being off is enforced through the boost_freq_req QoS request
+ * (capping policy->max) rather than by hiding the hardware maximum in
+ * cpuinfo, so sysfs keeps reflecting Notify(0x85) updates.
+ */
+static void cppc_cpufreq_sync_boost_limits(struct cpufreq_policy *policy,
+ bool boost_supported)
+{
+ struct cppc_cpudata *cpu_data = policy->driver_data;
+ struct cppc_perf_caps *caps = &cpu_data->perf_caps;
+ unsigned int highest_freq, nominal_freq, qos_freq;
+ int ret;
+
+ if (!boost_supported && policy->boost_enabled)
+ policy->boost_enabled = false;
+
+ policy->boost_supported = boost_supported;
+
+ highest_freq = cppc_perf_to_khz(caps, caps->highest_perf);
+ nominal_freq = cppc_perf_to_khz(caps, caps->nominal_perf);
+
+ policy->cpuinfo.max_freq = highest_freq;
+
+ if (boost_supported && !policy->boost_enabled)
+ qos_freq = nominal_freq;
+ else
+ qos_freq = highest_freq;
+
+ /* boost_freq_req only exists if boost was supported at policy init. */
+ if (freq_qos_request_active(&policy->boost_freq_req)) {
+ ret = freq_qos_update_request(&policy->boost_freq_req,
+ qos_freq);
+ if (ret < 0)
+ pr_err("CPU%d: failed to sync boost QoS: %pe\n",
+ policy->cpu, ERR_PTR(ret));
+ }
+}
+
+static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy)
+{
+ struct cppc_cpudata *cpu_data;
+ struct cppc_perf_caps *caps;
+ u64 prev_highest_perf;
+ u64 highest_perf;
+ int ret;
+
+ guard(cpufreq_policy_write)(policy);
+
+ if (policy_is_inactive(policy))
+ return;
+
+ cpu_data = policy->driver_data;
+ caps = &cpu_data->perf_caps;
+
+ prev_highest_perf = caps->highest_perf;
+
+ ret = cppc_get_highest_perf(policy->cpu, &highest_perf);
+ if (ret)
+ return;
+
+ if (highest_perf == prev_highest_perf)
+ return;
+
+ /*
+ * Cap increases at the Highest Performance probed at policy
+ * init: a value above it would let boost support appear on
+ * policies that started without boost, which the core cannot
+ * handle (the boost QoS request is created at init only).
+ * Within that bound both directions are accepted, e.g. a
+ * platform switching back to a performance mode.
+ */
+ if (highest_perf > cpu_data->init_highest_perf)
+ return;
+
+ /* A value below Nominal violates the CPPC invariant; ignore it. */
+ if (highest_perf < caps->nominal_perf) {
+ pr_warn("CPU%d: ignoring highest_perf %llu below nominal %u\n",
+ policy->cpu, highest_perf, caps->nominal_perf);
+ return;
+ }
+
+ caps->highest_perf = highest_perf;
+
+ /*
+ * Re-evaluate boost capability/status based on the updated Highest
+ * Performance. Boost is supported when highest_perf exceeds
+ * nominal_perf.
+ */
+ cppc_cpufreq_sync_boost_limits(policy,
+ highest_perf > caps->nominal_perf);
+
+ refresh_frequency_limits(policy);
+
+ pr_debug("CPU%d: highest_perf updated %llu -> %llu\n",
+ policy->cpu, prev_highest_perf, highest_perf);
+}
+
static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
{
struct cppc_cpudata *cpu_data = policy->driver_data;
@@ -1060,6 +1159,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
.init = cppc_cpufreq_cpu_init,
.exit = cppc_cpufreq_cpu_exit,
.set_boost = cppc_cpufreq_set_boost,
+ .update_limits = cppc_cpufreq_update_limits,
.attr = cppc_cpufreq_attr,
.name = "cppc_cpufreq",
};
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 5bcdb0e553b9..df43f2f2e79e 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -163,6 +163,7 @@ struct cppc_cpudata {
struct cppc_perf_caps perf_caps;
struct cppc_perf_ctrls perf_ctrls;
struct cppc_perf_fb_ctrs perf_fb_ctrs;
+ u32 init_highest_perf;
unsigned int shared_type;
cpumask_var_t shared_cpu_map;
};
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v6 2/3] cpufreq: cppc: Refactor autonomous perf bounds into helper
2026-11-11 8:50 [PATCH v6 0/3] cpufreq: cppc: Handle Highest Performance changes at runtime Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 1/3] cpufreq: cppc: Add update_limits support for Highest Performance changes Xueqin Luo
@ 2026-11-11 8:50 ` Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates Xueqin Luo
2 siblings, 0 replies; 5+ messages in thread
From: Xueqin Luo @ 2026-11-11 8:50 UTC (permalink / raw)
To: rafael, viresh.kumar, sudeep.holla
Cc: zhanjie9, christian.loehle, zhenglifeng1, sumitg, lenb,
maciej.wieczor-retman, pawel.chmielewski, gregkh, dakr, johan,
ionela.voinescu, pierre.gondois, linux-pm, linux-acpi,
linux-kernel, acpica-devel, driver-core, Xueqin Luo
Extract the autonomous selection performance bounds programming from
store_auto_select() into a reusable cppc_cpufreq_set_autonomous_perf()
helper. The helper saves and restores MIN/MAX performance on failure,
keeping the rollback logic co-located with the programming sequence.
Reuse the helper in cppc_cpufreq_update_limits() so that when
Highest Performance changes at runtime, the autonomous MIN/MAX
envelope is re-programmed against the updated capability. Add a
pr_debug message on failure for diagnostics.
Signed-off-by: Xueqin Luo <luoxueqin@kylinos.cn>
---
drivers/cpufreq/cppc_cpufreq.c | 49 +++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 13 deletions(-)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 3bca30f5c0d5..7dab6e046b9f 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -868,6 +868,29 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
return 0;
}
+/*
+ * Program the autonomous MIN/MAX_PERF bounds from the current policy
+ * limits, restoring the previous bounds if the write fails.
+ */
+static int cppc_cpufreq_set_autonomous_perf(struct cpufreq_policy *policy)
+{
+ struct cppc_cpudata *cpu_data = policy->driver_data;
+ u32 old_min_perf = cpu_data->perf_ctrls.min_perf;
+ u32 old_max_perf = cpu_data->perf_ctrls.max_perf;
+ int ret;
+
+ cppc_cpufreq_update_perf_limits(cpu_data, policy);
+
+ ret = cppc_set_perf(policy->cpu, &cpu_data->perf_ctrls);
+ if (ret) {
+ cpu_data->perf_ctrls.min_perf = old_min_perf;
+ cpu_data->perf_ctrls.max_perf = old_max_perf;
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* Boost being off is enforced through the boost_freq_req QoS request
* (capping policy->max) rather than by hiding the hardware maximum in
@@ -961,6 +984,18 @@ static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy)
refresh_frequency_limits(policy);
+ /*
+ * Autonomous selection mode uses MIN/MAX performance as runtime
+ * hardware control bounds. Re-program them when highest_perf
+ * changes so that the platform uses the updated bounds.
+ */
+ if (cpu_data->perf_ctrls.auto_sel) {
+ ret = cppc_cpufreq_set_autonomous_perf(policy);
+ if (ret)
+ pr_debug("CPU%d: failed to update autonomous perf: %d\n",
+ policy->cpu, ret);
+ }
+
pr_debug("CPU%d: highest_perf updated %llu -> %llu\n",
policy->cpu, prev_highest_perf, highest_perf);
}
@@ -1008,20 +1043,8 @@ static ssize_t store_auto_select(struct cpufreq_policy *policy,
cpu_data->perf_ctrls.auto_sel = val;
if (val) {
- u32 old_min_perf = cpu_data->perf_ctrls.min_perf;
- u32 old_max_perf = cpu_data->perf_ctrls.max_perf;
-
- /*
- * When enabling autonomous selection, program MIN_PERF and
- * MAX_PERF from current policy limits so that the platform
- * uses the correct performance bounds immediately.
- */
- cppc_cpufreq_update_perf_limits(cpu_data, policy);
-
- ret = cppc_set_perf(policy->cpu, &cpu_data->perf_ctrls);
+ ret = cppc_cpufreq_set_autonomous_perf(policy);
if (ret) {
- cpu_data->perf_ctrls.min_perf = old_min_perf;
- cpu_data->perf_ctrls.max_perf = old_max_perf;
cppc_set_auto_sel(policy->cpu, old_auto_sel);
cpu_data->perf_ctrls.auto_sel = old_auto_sel;
return ret;
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates
2026-11-11 8:50 [PATCH v6 0/3] cpufreq: cppc: Handle Highest Performance changes at runtime Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 1/3] cpufreq: cppc: Add update_limits support for Highest Performance changes Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 2/3] cpufreq: cppc: Refactor autonomous perf bounds into helper Xueqin Luo
@ 2026-11-11 8:50 ` Xueqin Luo
2026-11-11 14:14 ` kernel test robot
2 siblings, 1 reply; 5+ messages in thread
From: Xueqin Luo @ 2026-11-11 8:50 UTC (permalink / raw)
To: rafael, viresh.kumar, sudeep.holla
Cc: zhanjie9, christian.loehle, zhenglifeng1, sumitg, lenb,
maciej.wieczor-retman, pawel.chmielewski, gregkh, dakr, johan,
ionela.voinescu, pierre.gondois, linux-pm, linux-acpi,
linux-kernel, acpica-devel, driver-core, Xueqin Luo
When the CPPC Highest Performance register changes at runtime
(e.g. via ACPI Notify(0x85)), the scheduler's view of CPU capacity
and the frequency invariance engine's reference values become stale,
as topology_init_cpu_capacity_cppc() is only called once during boot.
Keep raw_capacity allocated after CPPC init instead of freeing it,
and introduce topology_update_cpu_capacity() to update per-CPU
raw_capacity, capacity_freq_ref, and the normalized CPU capacity
scale at runtime. Skip updates when the value is unchanged and
reject a zero capacity_scale to avoid division by zero.
Call this from cppc_cpufreq_update_limits() for every CPU in the
policy so shared-policy Notify(0x85) targeting a non-policy CPU
still refreshes the correct topology capacity.
Signed-off-by: Xueqin Luo <luoxueqin@kylinos.cn>
---
drivers/base/arch_topology.c | 77 ++++++++++++++++++++++++++++++++++
drivers/cpufreq/cppc_cpufreq.c | 10 ++++-
include/linux/arch_topology.h | 13 ++++++
3 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index e51fc9f5e976..f64f8e61f210 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -229,6 +229,7 @@ static void update_topology_flags_workfn(struct work_struct *work)
}
static u32 *raw_capacity;
+static DEFINE_MUTEX(raw_capacity_lock);
static int free_raw_capacity(void)
{
@@ -370,13 +371,89 @@ static inline void topology_init_cpu_capacity_cppc(void)
schedule_work(&update_topology_flags_work);
pr_debug("cpu_capacity: cpu_capacity initialization done\n");
+ /*
+ * Keep raw_capacity for runtime updates via
+ * topology_update_cpu_capacity().
+ */
+ return;
+
exit:
free_raw_capacity();
}
+
void acpi_processor_init_invariance_cppc(void)
{
topology_init_cpu_capacity_cppc();
}
+
+/**
+ * topology_update_cpu_capacity - Update CPU capacity after highest_perf change
+ * @cpu: CPU whose highest performance changed
+ * @perf_caps: Updated CPPC performance capabilities for @cpu
+ *
+ * When the CPPC Highest Performance register changes at runtime
+ * (e.g. via Notify(0x85)), the scheduler's view of CPU capacity
+ * and the frequency invariance engine's reference values become
+ * stale. This function updates the per-CPU raw_capacity,
+ * capacity_freq_ref and freq_inv max ratio, then re-normalizes the
+ * CPU capacity scale for all possible CPUs and triggers a sched
+ * domain rebuild. If the value is unchanged, everything is skipped.
+ */
+void topology_update_cpu_capacity(unsigned int cpu,
+ struct cppc_perf_caps *perf_caps)
+{
+ u32 highest_perf = perf_caps->highest_perf;
+ u64 capacity, capacity_scale = 0;
+ int c;
+
+ guard(mutex)(&raw_capacity_lock);
+
+ if (!raw_capacity || cpu >= num_possible_cpus())
+ return;
+
+ /*
+ * Validate: highest_perf must be >= nominal_perf and >= lowest_perf,
+ * consistent with the boot-time check in topology_init_cpu_capacity_cppc().
+ */
+ if (highest_perf < perf_caps->nominal_perf ||
+ highest_perf < perf_caps->lowest_perf) {
+ pr_warn("cpu_capacity: CPU%d invalid highest_perf=%u (nominal=%u, lowest=%u), skipping\n",
+ cpu, highest_perf, perf_caps->nominal_perf,
+ perf_caps->lowest_perf);
+ return;
+ }
+
+ if (raw_capacity[cpu] == highest_perf)
+ return;
+
+ pr_debug("cpu_capacity: CPU%d cpu_capacity=%u -> %u (raw)\n",
+ cpu, raw_capacity[cpu], highest_perf);
+
+ raw_capacity[cpu] = highest_perf;
+ per_cpu(capacity_freq_ref, cpu) =
+ cppc_perf_to_khz(perf_caps, highest_perf);
+ freq_inv_set_max_ratio(cpu,
+ per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
+
+ /* Re-normalize all CPUs: capacity is relative. */
+ for_each_possible_cpu(c)
+ capacity_scale = max_t(u64, capacity_scale, raw_capacity[c]);
+
+ if (!capacity_scale)
+ return;
+
+ for_each_possible_cpu(c) {
+ capacity = raw_capacity[c];
+ capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
+ capacity_scale);
+ topology_set_cpu_scale(c, capacity);
+ pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
+ c, topology_get_cpu_scale(c));
+ }
+
+ schedule_work(&update_topology_flags_work);
+}
+EXPORT_SYMBOL_GPL(topology_update_cpu_capacity);
#endif
#ifdef CONFIG_CPU_FREQ
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 7dab6e046b9f..a693ef611caa 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -935,7 +935,7 @@ static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy)
struct cppc_perf_caps *caps;
u64 prev_highest_perf;
u64 highest_perf;
- int ret;
+ int cpu, ret;
guard(cpufreq_policy_write)(policy);
@@ -984,6 +984,14 @@ static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy)
refresh_frequency_limits(policy);
+ /*
+ * All CPUs of the policy share perf_caps, and Notify(0x85) may
+ * target any CPU of a shared policy, so refresh the topology
+ * capacity for every CPU of the policy, including offline ones.
+ */
+ for_each_cpu(cpu, policy->related_cpus)
+ topology_update_cpu_capacity(cpu, caps);
+
/*
* Autonomous selection mode uses MIN/MAX performance as runtime
* hardware control bounds. Re-program them when highest_perf
diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
index ebd7f8935f96..9415cb6a6c2b 100644
--- a/include/linux/arch_topology.h
+++ b/include/linux/arch_topology.h
@@ -11,6 +11,19 @@
void topology_normalize_cpu_scale(void);
int topology_update_cpu_topology(void);
+#ifdef CONFIG_ACPI_CPPC_LIB
+struct cppc_perf_caps;
+#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY
+void topology_update_cpu_capacity(unsigned int cpu,
+ struct cppc_perf_caps *perf_caps);
+#else
+static inline void
+topology_update_cpu_capacity(unsigned int cpu, struct cppc_perf_caps *perf_caps)
+{
+}
+#endif
+#endif
+
struct device_node;
bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates
2026-11-11 8:50 ` [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates Xueqin Luo
@ 2026-11-11 14:14 ` kernel test robot
0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2026-11-11 14:14 UTC (permalink / raw)
To: Xueqin Luo, rafael, viresh.kumar, sudeep.holla
Cc: oe-kbuild-all, zhanjie9, christian.loehle, zhenglifeng1, sumitg,
lenb, maciej.wieczor-retman, pawel.chmielewski, gregkh, dakr,
johan, ionela.voinescu, pierre.gondois, linux-pm, linux-acpi,
linux-kernel, acpica-devel, driver-core, Xueqin Luo
Hi Xueqin,
kernel test robot noticed the following build warnings:
[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on driver-core/driver-core-next driver-core/driver-core-linus amd-pstate/linux-next amd-pstate/bleeding-edge linus/master v7.4-rc2]
[cannot apply to rafael-pm/linux-next rafael-pm/bleeding-edge next-20261110]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Xueqin-Luo/cpufreq-cppc-Add-update_limits-support-for-Highest-Performance-changes/20261111-165020
base: driver-core/driver-core-testing
patch link: https://lore.kernel.org/r/20261111085022.1229866-4-luoxueqin%40kylinos.cn
patch subject: [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates
config: riscv-allnoconfig (https://download.01.org/0day-ci/archive/20261111/202611112222.Q0bXZAjq-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 16.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261111/202611112222.Q0bXZAjq-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202611112222.Q0bXZAjq-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/seqlock.h:20,
from include/linux/mmzone.h:17,
from include/linux/gfp.h:7,
from include/linux/slab.h:17,
from include/linux/resource_ext.h:11,
from include/linux/acpi.h:14,
from drivers/base/arch_topology.c:9:
>> drivers/base/arch_topology.c:232:21: warning: 'raw_capacity_lock' defined but not used [-Wunused-variable]
232 | static DEFINE_MUTEX(raw_capacity_lock);
| ^~~~~~~~~~~~~~~~~
include/linux/mutex.h:87:22: note: in definition of macro 'DEFINE_MUTEX'
87 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
| ^~~~~~~~~
vim +/raw_capacity_lock +232 drivers/base/arch_topology.c
230
231 static u32 *raw_capacity;
> 232 static DEFINE_MUTEX(raw_capacity_lock);
233
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-11 14:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 8:50 [PATCH v6 0/3] cpufreq: cppc: Handle Highest Performance changes at runtime Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 1/3] cpufreq: cppc: Add update_limits support for Highest Performance changes Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 2/3] cpufreq: cppc: Refactor autonomous perf bounds into helper Xueqin Luo
2026-11-11 8:50 ` [PATCH v6 3/3] arch_topology: Add topology_update_cpu_capacity() for runtime updates Xueqin Luo
2026-11-11 14:14 ` kernel test robot
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®