* [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority
@ 2026-03-20 14:43 Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
` (11 more replies)
0 siblings, 12 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
Hello,
This is the v3 of the patchset to add support to the amd-pstate driver
for a new feature named "CPPC Performance Priority" that will be
available on some of the future AMD processors.
Details of the feature can be found in the AMD Publication titled
"AMD64 Collaborative Processor Performance Control (CPPC) Performance
Priority" (https://docs.amd.com/v/u/en-US/69206_1.10_AMD64_CPPC_PUB)
v2-->v3 changes:
* Picked up the Reviewed-by: tags from Mario except for Patches 5 and
6 which have major changes (see below)
* Patch 3: Fixed the subtle bug in amd_pstate_driver_cleanup() by cleaning
setting current_pstate_driver->attr to NULL [Claude Opus 4.6 +
review-prompts]
* Patch 5: Added bios_floor_perf field to struct amd_cpudata to cache
boot-time floor_perf value [New]
* Patch 5: Moved policy->driver_data = cpudata assignment earlier in
amd_pstate_cpu_init() (before amd_pstate_cppc_enable()) so that
policy->driver_data is valid when amd_pstate_init_floor_perf() is
called inside amd_pstate_cppc_enable() [Bug discovered while
running amd-pstate-ut tests]
* Patch 5: Added policy->driver_data = NULL in error paths of both
amd_pstate_cpu_init() and amd_pstate_epp_cpu_init() to clean up on
failure. [Code-Hardening]
* Patch 5: Restores bios_floor_perf via amd_pstate_set_floor_perf() in both
amd_pstate_cpu_exit() and amd_pstate_epp_cpu_exit() [New]
* Patch 6: Added input validation in store_amd_pstate_floor_freq():
rejects frequencies outside [cpuinfo_min_freq, scaling_max_freq]
with -EINVAL. [Code Hardening]
* Patch 6: Removed stray blank line between
show_amd_pstate_floor_freq() and
show_amd_pstate_floor_count(). [Mario]
* Patch 6: Reset the floor_perf to bios_floor_perf in the suspend,
offline, and exit paths, and restore the value to the cached
user-request floor_freq on the resume and online paths mirroring
how bios_min_perf is handled for MSR_AMD_CPPC_REQ [New]
* Patch 8: Add the capability to run a single test from amd_pstate_ut [New]
* Patch 9: New unit test to validate the driver->attrs [Mario]
* Patch 10 and 11: Split the Documentation fixes for
amd_pstate_hw_prefcore and amd_pstate_prefcore_ranking into two
different patches [Mario]
v1 --> v2 Changes:
* Picked up the Reviewed-by: tags from Boris and Mario for a couple of patches.
* Defined AMD_CPPC_FLOOR_PERF_CNT_MASK via GENMASK_ULL() instead of
GENMASK() to fix the build errors reported by the kernel test robot
(https://lore.kernel.org/lkml/202603070431.ykswVnpp-lkp@intel.com/)
* Moved the code from amd_pstate_cache_cppc_req2() into
amd_pstate_init_floor_perf() since there are no other callers of
amd_pstate_cache_cppc_req2().
* Cached the user requested amd_pstate_floor_freq into
cpudata->floor_freq [Prateek] and return the same when the user
reads the syfs file.
Description:
This feature allows userspace to specify different floor performance
levels for different CPUs. The platform firmware takes these different
floor performance levels into consideration while throttling the CPUs
under power/thermal constraints.
The presence of this feature is advertised through bit 16 of EDX
register for CPUID leaf 0x80000007. The number of distinct floor
performance levels supported on the platform will be advertised
through the bits 32:39 of the MSR_AMD_CPPC_CAP1. Bits 0:7 of a new MSR
MSR_AMD_CPPC_REQ2 (0xc00102b5) will be used to specify the desired
floor performance level for that CPU.
Key changes made by this patchset:
* Fix a memory leak bug and a control-flow bug.
* Plumb in proper visibility controls for the freq_attr attributes
so that only relevant attributes can be made visible depending on
the underlying platform and the current amd-pstate driver mode.
* Add support for the new CPUID bits, the new MSR and parsing bits
32:39 of MSR_AMD_CPPC_CAP1.
* Set the default value for MSR_AMD_CPPC_REQ2[0:7] (Floor perf) to
CPPC.nominal_perf when the value at boot-time is lower than
CPPC.lowest_perf
* Add sysfs support for floor_freq and floor_count
* Add a new unit-test in amd-pstate-ut to validate the driver
freq_attrs.
* Introduce a tracepoint trace_amd_pstate_cppc_req2 for tracking
the updates to MSR_AMD_CPPC_REQ2.
* Add documentation for amd_pstate_floor_{freq,count}
Gautham R. Shenoy (12):
amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init()
amd-pstate: Update cppc_req_cached in fast_switch case
amd-pstate: Make certain freq_attrs conditionally visible
x86/cpufeatures: Add AMD CPPC Performance Priority feature.
amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
amd-pstate: Add sysfs support for floor_freq and floor_count
amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2()
amd-pstate-ut: Add ability to run a single testcase
amd-pstate-ut: Add a testcase to validate the visibility of driver attributes
Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file
Documentation/amd-pstate: List amd_pstate_prefcore_ranking sysfs file
Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count}
Documentation/admin-guide/pm/amd-pstate.rst | 42 ++-
arch/x86/include/asm/cpufeatures.h | 2 +-
arch/x86/include/asm/msr-index.h | 5 +
arch/x86/kernel/cpu/scattered.c | 1 +
drivers/cpufreq/amd-pstate-trace.h | 35 +++
drivers/cpufreq/amd-pstate-ut.c | 150 +++++++++-
drivers/cpufreq/amd-pstate.c | 312 +++++++++++++++++---
drivers/cpufreq/amd-pstate.h | 12 +
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
9 files changed, 511 insertions(+), 50 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init()
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 02/12] amd-pstate: Update cppc_req_cached in fast_switch case Gautham R. Shenoy
` (10 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Mario Limonciello
On failure to set the epp, the function amd_pstate_epp_cpu_init()
returns with an error code without freeing the cpudata object that was
allocated at the beginning of the function.
Ensure that the cpudata object is freed before returning from the
function.
This memory leak was discovered by Claude Opus 4.6 with the aid of
Chris Mason's AI review-prompts
(https://github.com/masoncl/review-prompts/tree/main/kernel).
Assisted-by: Claude:claude-opus-4.6 review-prompts/linux
Fixes: f9a378ff6443 ("cpufreq/amd-pstate: Set different default EPP policy for Epyc and Ryzen")
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 5aa9fcd80cf5..d57969c72c9d 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1533,7 +1533,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
ret = amd_pstate_set_epp(policy, cpudata->epp_default);
if (ret)
- return ret;
+ goto free_cpudata1;
current_pstate_driver->adjust_perf = NULL;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 02/12] amd-pstate: Update cppc_req_cached in fast_switch case
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 03/12] amd-pstate: Make certain freq_attrs conditionally visible Gautham R. Shenoy
` (9 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Mario Limonciello
The function msr_update_perf() does not cache the new value that is
written to MSR_AMD_CPPC_REQ into the variable cpudata->cppc_req_cached
when the update is happening from the fast path.
Fix that by caching the value everytime the MSR_AMD_CPPC_REQ gets
updated.
This issue was discovered by Claude Opus 4.6 with the aid of Chris
Mason's AI review-prompts
(https://github.com/masoncl/review-prompts/tree/main/kernel).
Assisted-by: Claude:claude-opus-4.6 review-prompts/linux
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Fixes: fff395796917 ("cpufreq/amd-pstate: Always write EPP value when updating perf")
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index d57969c72c9d..24cdeffbcd40 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -261,7 +261,6 @@ static int msr_update_perf(struct cpufreq_policy *policy, u8 min_perf,
if (fast_switch) {
wrmsrq(MSR_AMD_CPPC_REQ, value);
- return 0;
} else {
int ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 03/12] amd-pstate: Make certain freq_attrs conditionally visible
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 02/12] amd-pstate: Update cppc_req_cached in fast_switch case Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature Gautham R. Shenoy
` (8 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Mario Limonciello
Certain amd_pstate freq_attrs such as amd_pstate_hw_prefcore and
amd_pstate_prefcore_ranking are enabled even when preferred core is
not supported on the platform.
Similarly there are common freq_attrs between the amd-pstate and the
amd-pstate-epp drivers (eg: amd_pstate_max_freq,
amd_pstate_lowest_nonlinear_freq, etc.) but are duplicated in two
different freq_attr structs.
Unify all the attributes in a single place and associate each of them
with a visibility function that determines whether the attribute
should be visible based on the underlying platform support and the
current amd_pstate mode.
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate.c | 124 ++++++++++++++++++++++++++---------
1 file changed, 93 insertions(+), 31 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 24cdeffbcd40..4de2037a414c 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1220,12 +1220,87 @@ static ssize_t show_energy_performance_preference(
return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
}
+cpufreq_freq_attr_ro(amd_pstate_max_freq);
+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
+
+cpufreq_freq_attr_ro(amd_pstate_highest_perf);
+cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
+cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
+cpufreq_freq_attr_rw(energy_performance_preference);
+cpufreq_freq_attr_ro(energy_performance_available_preferences);
+
+struct freq_attr_visibility {
+ struct freq_attr *attr;
+ bool (*visibility_fn)(void);
+};
+
+/* For attributes which are always visible */
+static bool always_visible(void)
+{
+ return true;
+}
+
+/* Determines whether prefcore related attributes should be visible */
+static bool prefcore_visibility(void)
+{
+ return amd_pstate_prefcore;
+}
+
+/* Determines whether energy performance preference should be visible */
+static bool epp_visibility(void)
+{
+ return cppc_state == AMD_PSTATE_ACTIVE;
+}
+
+static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
+ {&amd_pstate_max_freq, always_visible},
+ {&amd_pstate_lowest_nonlinear_freq, always_visible},
+ {&amd_pstate_highest_perf, always_visible},
+ {&amd_pstate_prefcore_ranking, prefcore_visibility},
+ {&amd_pstate_hw_prefcore, prefcore_visibility},
+ {&energy_performance_preference, epp_visibility},
+ {&energy_performance_available_preferences, epp_visibility},
+};
+
+static struct freq_attr **get_freq_attrs(void)
+{
+ bool attr_visible[ARRAY_SIZE(amd_pstate_attr_visibility)];
+ struct freq_attr **attrs;
+ int i, j, count;
+
+ for (i = 0, count = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
+ struct freq_attr_visibility *v = &amd_pstate_attr_visibility[i];
+
+ attr_visible[i] = v->visibility_fn();
+ if (attr_visible[i])
+ count++;
+ }
+
+ /* amd_pstate_{max_freq, lowest_nonlinear_freq, highest_perf} should always be visible */
+ BUG_ON(!count);
+
+ attrs = kcalloc(count + 1, sizeof(struct freq_attr *), GFP_KERNEL);
+ if (!attrs)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
+ if (!attr_visible[i])
+ continue;
+
+ attrs[j++] = amd_pstate_attr_visibility[i].attr;
+ }
+
+ return attrs;
+}
+
static void amd_pstate_driver_cleanup(void)
{
if (amd_pstate_prefcore)
sched_clear_itmt_support();
cppc_state = AMD_PSTATE_DISABLE;
+ kfree(current_pstate_driver->attr);
+ current_pstate_driver->attr = NULL;
current_pstate_driver = NULL;
}
@@ -1250,6 +1325,7 @@ static int amd_pstate_set_driver(int mode_idx)
static int amd_pstate_register_driver(int mode)
{
+ struct freq_attr **attr = NULL;
int ret;
ret = amd_pstate_set_driver(mode);
@@ -1258,6 +1334,22 @@ static int amd_pstate_register_driver(int mode)
cppc_state = mode;
+ /*
+ * Note: It is important to compute the attrs _after_
+ * re-initializing the cppc_state. Some attributes become
+ * visible only when cppc_state is AMD_PSTATE_ACTIVE.
+ */
+ attr = get_freq_attrs();
+ if (IS_ERR(attr)) {
+ ret = (int) PTR_ERR(attr);
+ pr_err("Couldn't compute freq_attrs for current mode %s [%d]\n",
+ amd_pstate_get_mode_string(cppc_state), ret);
+ amd_pstate_driver_cleanup();
+ return ret;
+ }
+
+ current_pstate_driver->attr = attr;
+
/* at least one CPU supports CPB */
current_pstate_driver->boost_enabled = cpu_feature_enabled(X86_FEATURE_CPB);
@@ -1399,37 +1491,9 @@ static ssize_t prefcore_show(struct device *dev,
return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore));
}
-cpufreq_freq_attr_ro(amd_pstate_max_freq);
-cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
-
-cpufreq_freq_attr_ro(amd_pstate_highest_perf);
-cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
-cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
-cpufreq_freq_attr_rw(energy_performance_preference);
-cpufreq_freq_attr_ro(energy_performance_available_preferences);
static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(prefcore);
-static struct freq_attr *amd_pstate_attr[] = {
- &amd_pstate_max_freq,
- &amd_pstate_lowest_nonlinear_freq,
- &amd_pstate_highest_perf,
- &amd_pstate_prefcore_ranking,
- &amd_pstate_hw_prefcore,
- NULL,
-};
-
-static struct freq_attr *amd_pstate_epp_attr[] = {
- &amd_pstate_max_freq,
- &amd_pstate_lowest_nonlinear_freq,
- &amd_pstate_highest_perf,
- &amd_pstate_prefcore_ranking,
- &amd_pstate_hw_prefcore,
- &energy_performance_preference,
- &energy_performance_available_preferences,
- NULL,
-};
-
static struct attribute *pstate_global_attributes[] = {
&dev_attr_status.attr,
&dev_attr_prefcore.attr,
@@ -1696,7 +1760,6 @@ static struct cpufreq_driver amd_pstate_driver = {
.set_boost = amd_pstate_set_boost,
.update_limits = amd_pstate_update_limits,
.name = "amd-pstate",
- .attr = amd_pstate_attr,
};
static struct cpufreq_driver amd_pstate_epp_driver = {
@@ -1712,7 +1775,6 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.update_limits = amd_pstate_update_limits,
.set_boost = amd_pstate_set_boost,
.name = "amd-pstate-epp",
- .attr = amd_pstate_epp_attr,
};
/*
@@ -1858,7 +1920,7 @@ static int __init amd_pstate_init(void)
return ret;
global_attr_free:
- cpufreq_unregister_driver(current_pstate_driver);
+ amd_pstate_unregister_driver(0);
return ret;
}
device_initcall(amd_pstate_init);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature.
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (2 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 03/12] amd-pstate: Make certain freq_attrs conditionally visible Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
` (7 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, H. Peter Anvin,
Borislav Petkov, Dave Hansen, Thomas Gleixner, Ingo Molnar, x86
Some future AMD processors have feature named "CPPC Performance
Priority" which lets userspace specify different floor performance
levels for different CPUs. The platform firmware takes these different
floor performance levels into consideration while throttling the CPUs
under power/thermal constraints. The presence of this feature is
indicated by bit 16 of the EDX register for CPUID leaf
0x80000007. More details can be found in AMD Publication titled "AMD64
Collaborative Processor Performance Control (CPPC) Performance
Priority" Revision 1.10.
Define a new feature bit named X86_FEATURE_CPPC_PERF_PRIO to map to
CPUID 0x80000007.EDX[16].
Reviewed-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
arch/x86/include/asm/cpufeatures.h | 2 +-
arch/x86/kernel/cpu/scattered.c | 1 +
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index dbe104df339b..86d17b195e79 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -415,7 +415,7 @@
*/
#define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* "overflow_recov" MCA overflow recovery support */
#define X86_FEATURE_SUCCOR (17*32+ 1) /* "succor" Uncorrectable error containment and recovery */
-
+#define X86_FEATURE_CPPC_PERF_PRIO (17*32+ 2) /* CPPC Floor Perf support */
#define X86_FEATURE_SMCA (17*32+ 3) /* "smca" Scalable MCA */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 42c7eac0c387..837d6a4b0c28 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -52,6 +52,7 @@ static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 },
{ X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 },
{ X86_FEATURE_AMD_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
+ { X86_FEATURE_CPPC_PERF_PRIO, CPUID_EDX, 16, 0x80000007, 0 },
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
{ X86_FEATURE_X2AVIC_EXT, CPUID_ECX, 6, 0x8000000a, 0 },
{ X86_FEATURE_COHERENCY_SFW_NO, CPUID_EBX, 31, 0x8000001f, 0 },
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index dbe104df339b..86d17b195e79 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -415,7 +415,7 @@
*/
#define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* "overflow_recov" MCA overflow recovery support */
#define X86_FEATURE_SUCCOR (17*32+ 1) /* "succor" Uncorrectable error containment and recovery */
-
+#define X86_FEATURE_CPPC_PERF_PRIO (17*32+ 2) /* CPPC Floor Perf support */
#define X86_FEATURE_SMCA (17*32+ 3) /* "smca" Scalable MCA */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (3 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-24 21:38 ` Mario Limonciello
2026-03-20 14:43 ` [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
` (6 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
Some future AMD processors have feature named "CPPC Performance
Priority" which lets userspace specify different floor performance
levels for different CPUs. The platform firmware takes these different
floor performance levels into consideration while throttling the CPUs
under power/thermal constraints. The presence of this feature is
indicated by bit 16 of the EDX register for CPUID leaf
0x80000007. More details can be found in AMD Publication titled "AMD64
Collaborative Processor Performance Control (CPPC) Performance
Priority" Revision 1.10.
The number of distinct floor performance levels supported on the
platform will be advertised through the bits 32:39 of the
MSR_AMD_CPPC_CAP1. Bits 0:7 of a new MSR MSR_AMD_CPPC_REQ2
(0xc00102b5) will be used to specify the desired floor performance
level for that CPU.
Add support for the aforementioned MSR_AMD_CPPC_REQ2, and macros for
parsing and updating the relevant bits from MSR_AMD_CPPC_CAP1 and
MSR_AMD_CPPC_REQ2.
On boot if the default value of the MSR_AMD_CPPC_REQ2[7:0] (Floor
Perf) is lower than CPPC.lowest_perf, and thus invalid, initialize it
to MSR_AMD_CPPC_CAP1.nominal_perf which is a sane default value.
Save the boot-time floor_perf during amd_pstate_init_floor_perf(). In
a subsequent patch it will be restored in the suspend, offline, and
exit paths, mirroring how bios_min_perf is handled for
MSR_AMD_CPPC_REQ.
Link: https://docs.amd.com/v/u/en-US/69206_1.10_AMD64_CPPC_PUB
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
arch/x86/include/asm/msr-index.h | 5 ++
drivers/cpufreq/amd-pstate.c | 78 +++++++++++++++++++++++++++++++-
drivers/cpufreq/amd-pstate.h | 6 +++
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6673601246b3..e126c7fb69cf 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -765,12 +765,14 @@
#define MSR_AMD_CPPC_CAP2 0xc00102b2
#define MSR_AMD_CPPC_REQ 0xc00102b3
#define MSR_AMD_CPPC_STATUS 0xc00102b4
+#define MSR_AMD_CPPC_REQ2 0xc00102b5
/* Masks for use with MSR_AMD_CPPC_CAP1 */
#define AMD_CPPC_LOWEST_PERF_MASK GENMASK(7, 0)
#define AMD_CPPC_LOWNONLIN_PERF_MASK GENMASK(15, 8)
#define AMD_CPPC_NOMINAL_PERF_MASK GENMASK(23, 16)
#define AMD_CPPC_HIGHEST_PERF_MASK GENMASK(31, 24)
+#define AMD_CPPC_FLOOR_PERF_CNT_MASK GENMASK_ULL(39, 32)
/* Masks for use with MSR_AMD_CPPC_REQ */
#define AMD_CPPC_MAX_PERF_MASK GENMASK(7, 0)
@@ -778,6 +780,9 @@
#define AMD_CPPC_DES_PERF_MASK GENMASK(23, 16)
#define AMD_CPPC_EPP_PERF_MASK GENMASK(31, 24)
+/* Masks for use with MSR_AMD_CPPC_REQ2 */
+#define AMD_CPPC_FLOOR_PERF_MASK GENMASK(7, 0)
+
/* AMD Performance Counter Global Status and Control MSRs */
#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300
#define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 4de2037a414c..53b8173ff183 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -329,6 +329,65 @@ static inline int amd_pstate_set_epp(struct cpufreq_policy *policy, u8 epp)
return static_call(amd_pstate_set_epp)(policy, epp);
}
+static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+ u64 value, prev;
+ int ret;
+
+ if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
+ return 0;
+
+ value = prev = READ_ONCE(cpudata->cppc_req2_cached);
+ FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);
+
+ if (value == prev)
+ return 0;
+
+ ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
+ if (ret) {
+ pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
+ return ret;
+ }
+
+ WRITE_ONCE(cpudata->cppc_req2_cached, value);
+
+ return ret;
+}
+
+static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+ u8 floor_perf;
+ u64 value;
+ int ret;
+
+ if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
+ return 0;
+
+ ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, &value);
+ if (ret) {
+ pr_err("failed to read CPPC REQ2 value. Error (%d)\n", ret);
+ return ret;
+ }
+
+ WRITE_ONCE(cpudata->cppc_req2_cached, value);
+ floor_perf = FIELD_GET(AMD_CPPC_FLOOR_PERF_MASK,
+ cpudata->cppc_req2_cached);
+
+ /* Set a sane value for floor_perf if the default value is invalid */
+ if (floor_perf < cpudata->perf.lowest_perf) {
+ floor_perf = cpudata->perf.nominal_perf;
+ ret = amd_pstate_set_floor_perf(policy, floor_perf);
+ if (ret)
+ return ret;
+ }
+
+ cpudata->bios_floor_perf = floor_perf;
+
+ return 0;
+}
+
static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
{
struct amd_cpudata *cpudata = policy->driver_data;
@@ -426,6 +485,7 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
perf.lowest_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
WRITE_ONCE(cpudata->perf, perf);
WRITE_ONCE(cpudata->prefcore_ranking, FIELD_GET(AMD_CPPC_HIGHEST_PERF_MASK, cap1));
+ WRITE_ONCE(cpudata->floor_perf_cnt, FIELD_GET(AMD_CPPC_FLOOR_PERF_CNT_MASK, cap1));
return 0;
}
@@ -1024,6 +1084,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
cpudata->nominal_freq,
perf.highest_perf);
+ policy->driver_data = cpudata;
ret = amd_pstate_cppc_enable(policy);
if (ret)
goto free_cpudata1;
@@ -1036,6 +1097,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
if (cpu_feature_enabled(X86_FEATURE_CPPC))
policy->fast_switch_possible = true;
+ ret = amd_pstate_init_floor_perf(policy);
+ if (ret) {
+ dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
+ goto free_cpudata1;
+ }
+
ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
if (ret < 0) {
@@ -1050,7 +1117,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
goto free_cpudata2;
}
- policy->driver_data = cpudata;
if (!current_pstate_driver->adjust_perf)
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
@@ -1062,6 +1128,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
free_cpudata1:
pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
kfree(cpudata);
+ policy->driver_data = NULL;
return ret;
}
@@ -1072,6 +1139,7 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
/* Reset CPPC_REQ MSR to the BIOS value */
amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
+ amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
freq_qos_remove_request(&cpudata->req[1]);
freq_qos_remove_request(&cpudata->req[0]);
@@ -1598,6 +1666,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
if (ret)
goto free_cpudata1;
+ ret = amd_pstate_init_floor_perf(policy);
+ if (ret) {
+ dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
+ goto free_cpudata1;
+ }
+
current_pstate_driver->adjust_perf = NULL;
return 0;
@@ -1605,6 +1679,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
free_cpudata1:
pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
kfree(cpudata);
+ policy->driver_data = NULL;
return ret;
}
@@ -1617,6 +1692,7 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
/* Reset CPPC_REQ MSR to the BIOS value */
amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
+ amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
kfree(cpudata);
policy->driver_data = NULL;
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index cb45fdca27a6..f04561da4518 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -62,9 +62,12 @@ struct amd_aperf_mperf {
* @cpu: CPU number
* @req: constraint request to apply
* @cppc_req_cached: cached performance request hints
+ * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
* @perf: cached performance-related data
* @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
* priority.
+ * @floor_perf_cnt: Cached value of the number of distinct floor
+ * performance levels supported
* @min_limit_freq: Cached value of policy->min (in khz)
* @max_limit_freq: Cached value of policy->max (in khz)
* @nominal_freq: the frequency (in khz) that mapped to nominal_perf
@@ -87,10 +90,13 @@ struct amd_cpudata {
struct freq_qos_request req[2];
u64 cppc_req_cached;
+ u64 cppc_req2_cached;
union perf_cached perf;
u8 prefcore_ranking;
+ u8 floor_perf_cnt;
+ u8 bios_floor_perf;
u32 min_limit_freq;
u32 max_limit_freq;
u32 nominal_freq;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (4 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-24 21:39 ` Mario Limonciello
2026-03-20 14:43 ` [PATCH v3 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2() Gautham R. Shenoy
` (5 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
When Floor Performance feature is supported by the platform, expose
two sysfs files:
* amd_pstate_floor_freq to allow userspace to request the floor
frequency for each CPU.
* amd_pstate_floor_count which advertises the number of distinct
levels of floor frequencies supported on this platform.
Reset the floor_perf to bios_floor_perf in the suspend, offline, and
exit paths, and restore the value to the cached user-request
floor_freq on the resume and online paths mirroring how bios_min_perf
is handled for MSR_AMD_CPPC_REQ.
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate.c | 93 +++++++++++++++++++++++++++++++++---
drivers/cpufreq/amd-pstate.h | 2 +
2 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 53b8173ff183..a068c4457a8f 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -383,8 +383,10 @@ static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
return ret;
}
- cpudata->bios_floor_perf = floor_perf;
+ cpudata->bios_floor_perf = floor_perf;
+ cpudata->floor_freq = perf_to_freq(cpudata->perf, cpudata->nominal_freq,
+ floor_perf);
return 0;
}
@@ -1288,6 +1290,46 @@ static ssize_t show_energy_performance_preference(
return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
}
+static ssize_t store_amd_pstate_floor_freq(struct cpufreq_policy *policy,
+ const char *buf, size_t count)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+ union perf_cached perf = READ_ONCE(cpudata->perf);
+ unsigned int freq;
+ u8 floor_perf;
+ int ret;
+
+ ret = kstrtouint(buf, 0, &freq);
+ if (ret)
+ return ret;
+
+ if (freq < policy->cpuinfo.min_freq || freq > policy->max)
+ return -EINVAL;
+
+ floor_perf = freq_to_perf(perf, cpudata->nominal_freq, freq);
+ ret = amd_pstate_set_floor_perf(policy, floor_perf);
+
+ if (!ret)
+ cpudata->floor_freq = freq;
+
+ return ret ?: count;
+}
+
+static ssize_t show_amd_pstate_floor_freq(struct cpufreq_policy *policy, char *buf)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+
+ return sysfs_emit(buf, "%u\n", cpudata->floor_freq);
+}
+
+static ssize_t show_amd_pstate_floor_count(struct cpufreq_policy *policy, char *buf)
+{
+ struct amd_cpudata *cpudata = policy->driver_data;
+ u8 count = cpudata->floor_perf_cnt;
+
+ return sysfs_emit(buf, "%u\n", count);
+}
+
cpufreq_freq_attr_ro(amd_pstate_max_freq);
cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
@@ -1296,6 +1338,8 @@ cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
cpufreq_freq_attr_rw(energy_performance_preference);
cpufreq_freq_attr_ro(energy_performance_available_preferences);
+cpufreq_freq_attr_rw(amd_pstate_floor_freq);
+cpufreq_freq_attr_ro(amd_pstate_floor_count);
struct freq_attr_visibility {
struct freq_attr *attr;
@@ -1320,6 +1364,12 @@ static bool epp_visibility(void)
return cppc_state == AMD_PSTATE_ACTIVE;
}
+/* Determines whether amd_pstate_floor_freq related attributes should be visible */
+static bool floor_freq_visibility(void)
+{
+ return cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO);
+}
+
static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
{&amd_pstate_max_freq, always_visible},
{&amd_pstate_lowest_nonlinear_freq, always_visible},
@@ -1328,6 +1378,8 @@ static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
{&amd_pstate_hw_prefcore, prefcore_visibility},
{&energy_performance_preference, epp_visibility},
{&energy_performance_available_preferences, epp_visibility},
+ {&amd_pstate_floor_freq, floor_freq_visibility},
+ {&amd_pstate_floor_count, floor_freq_visibility},
};
static struct freq_attr **get_freq_attrs(void)
@@ -1748,24 +1800,39 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
static int amd_pstate_cpu_online(struct cpufreq_policy *policy)
{
- return amd_pstate_cppc_enable(policy);
+ struct amd_cpudata *cpudata = policy->driver_data;
+ union perf_cached perf = READ_ONCE(cpudata->perf);
+ u8 cached_floor_perf;
+ int ret;
+
+ ret = amd_pstate_cppc_enable(policy);
+ if (ret)
+ return ret;
+
+ cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
+ return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}
static int amd_pstate_cpu_offline(struct cpufreq_policy *policy)
{
struct amd_cpudata *cpudata = policy->driver_data;
union perf_cached perf = READ_ONCE(cpudata->perf);
+ int ret;
/*
* Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
* min_perf value across kexec reboots. If this CPU is just onlined normally after this, the
* limits, epp and desired perf will get reset to the cached values in cpudata struct
*/
- return amd_pstate_update_perf(policy, perf.bios_min_perf,
+ ret = amd_pstate_update_perf(policy, perf.bios_min_perf,
FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached),
FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached),
FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached),
false);
+ if (ret)
+ return ret;
+
+ return amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
}
static int amd_pstate_suspend(struct cpufreq_policy *policy)
@@ -1787,6 +1854,10 @@ static int amd_pstate_suspend(struct cpufreq_policy *policy)
if (ret)
return ret;
+ ret = amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
+ if (ret)
+ return ret;
+
/* set this flag to avoid setting core offline*/
cpudata->suspended = true;
@@ -1798,15 +1869,24 @@ static int amd_pstate_resume(struct cpufreq_policy *policy)
struct amd_cpudata *cpudata = policy->driver_data;
union perf_cached perf = READ_ONCE(cpudata->perf);
int cur_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->cur);
+ u8 cached_floor_perf;
+ int ret;
/* Set CPPC_REQ to last sane value until the governor updates it */
- return amd_pstate_update_perf(policy, perf.min_limit_perf, cur_perf, perf.max_limit_perf,
- 0U, false);
+ ret = amd_pstate_update_perf(policy, perf.min_limit_perf, cur_perf, perf.max_limit_perf,
+ 0U, false);
+ if (ret)
+ return ret;
+
+ cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
+ return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}
static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
{
struct amd_cpudata *cpudata = policy->driver_data;
+ union perf_cached perf = READ_ONCE(cpudata->perf);
+ u8 cached_floor_perf;
if (cpudata->suspended) {
int ret;
@@ -1819,7 +1899,8 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
cpudata->suspended = false;
}
- return 0;
+ cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
+ return amd_pstate_set_floor_perf(policy, cached_floor_perf);
}
static struct cpufreq_driver amd_pstate_driver = {
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index f04561da4518..2f7a96836fcd 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -72,6 +72,7 @@ struct amd_aperf_mperf {
* @max_limit_freq: Cached value of policy->max (in khz)
* @nominal_freq: the frequency (in khz) that mapped to nominal_perf
* @lowest_nonlinear_freq: the frequency (in khz) that mapped to lowest_nonlinear_perf
+ * @floor_freq: Cached value of the user requested floor_freq
* @cur: Difference of Aperf/Mperf/tsc count between last and current sample
* @prev: Last Aperf/Mperf/tsc count value read from register
* @freq: current cpu frequency value (in khz)
@@ -101,6 +102,7 @@ struct amd_cpudata {
u32 max_limit_freq;
u32 nominal_freq;
u32 lowest_nonlinear_freq;
+ u32 floor_freq;
struct amd_aperf_mperf cur;
struct amd_aperf_mperf prev;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2()
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (5 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase Gautham R. Shenoy
` (4 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
Introduce a new tracepoint trace_amd_pstate_cppc_req2() to track
updates to MSR_AMD_CPPC_REQ2.
Invoke this while changing the Floor Perf.
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate-trace.h | 35 ++++++++++++++++++++++++++++++
drivers/cpufreq/amd-pstate.c | 14 +++++++++---
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
index 32e1bdc588c5..91fa073b2be4 100644
--- a/drivers/cpufreq/amd-pstate-trace.h
+++ b/drivers/cpufreq/amd-pstate-trace.h
@@ -133,6 +133,41 @@ TRACE_EVENT(amd_pstate_epp_perf,
)
);
+TRACE_EVENT(amd_pstate_cppc_req2,
+
+ TP_PROTO(unsigned int cpu_id,
+ u8 floor_perf,
+ bool changed,
+ int err_code
+ ),
+
+ TP_ARGS(cpu_id,
+ floor_perf,
+ changed,
+ err_code),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, cpu_id)
+ __field(u8, floor_perf)
+ __field(bool, changed)
+ __field(int, err_code)
+ ),
+
+ TP_fast_assign(
+ __entry->cpu_id = cpu_id;
+ __entry->floor_perf = floor_perf;
+ __entry->changed = changed;
+ __entry->err_code = err_code;
+ ),
+
+ TP_printk("cpu%u: floor_perf=%u, changed=%u (error = %d)",
+ __entry->cpu_id,
+ __entry->floor_perf,
+ __entry->changed,
+ __entry->err_code
+ )
+);
+
#endif /* _AMD_PSTATE_TRACE_H */
/* This part must be outside protection */
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index a068c4457a8f..5eae74a67aeb 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -333,6 +333,7 @@ static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
{
struct amd_cpudata *cpudata = policy->driver_data;
u64 value, prev;
+ bool changed;
int ret;
if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
@@ -341,17 +342,24 @@ static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
value = prev = READ_ONCE(cpudata->cppc_req2_cached);
FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);
- if (value == prev)
- return 0;
+ changed = value != prev;
+ if (!changed) {
+ ret = 0;
+ goto out_trace;
+ }
ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
if (ret) {
+ changed = false;
pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
- return ret;
+ goto out_trace;
}
WRITE_ONCE(cpudata->cppc_req2_cached, value);
+out_trace:
+ if (trace_amd_pstate_cppc_req2_enabled())
+ trace_amd_pstate_cppc_req2(cpudata->cpu, perf, changed, ret);
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (6 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2() Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-23 20:21 ` Mario Limonciello (AMD) (kernel.org)
2026-03-20 14:43 ` [PATCH v3 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes Gautham R. Shenoy
` (3 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
Currently when amd-pstate-ut test module is loaded, it runs all the
tests from amd_pstate_ut_cases[] array.
Add a module parameter named "run_only" that allows users to run a
single test from the array by specifying the test name string.
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 447b9aa5ce40..35e453a49c0f 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -35,6 +35,10 @@
#include "amd-pstate.h"
+static char *run_only;
+module_param(run_only, charp, 0444);
+MODULE_PARM_DESC(run_only,
+ "Run only the named test case (default: run all)");
struct amd_pstate_ut_struct {
const char *name;
@@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
for (i = 0; i < arr_size; i++) {
- int ret = amd_pstate_ut_cases[i].func(i);
+ int ret;
+
+ if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
+ continue;
+
+ ret = amd_pstate_ut_cases[i].func(i);
if (ret)
pr_err("%-4d %-20s\t fail: %d!\n", i+1, amd_pstate_ut_cases[i].name, ret);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (7 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file Gautham R. Shenoy
` (2 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy
amd-pstate driver has per-attribute visibility functions to
dynamically control which sysfs freq_attrs are exposed based on the
platform capabilities and the current amd_pstate mode. However, there
is no test coverage to validate that the driver's live attribute list
matches the expected visibility for each mode.
Add amd_pstate_ut_check_freq_attrs() to the amd-pstate unit test
module. For each enabled mode (passive, active, guided), the test
independently derives the expected visibility of each attribute:
- Core attributes (max_freq, lowest_nonlinear_freq, highest_perf)
are always expected.
- Prefcore attributes (prefcore_ranking, hw_prefcore) are expected
only when cpudata->hw_prefcore indicates platform support.
- EPP attributes (energy_performance_preference,
energy_performance_available_preferences) are expected only in
active mode.
- Floor frequency attributes (floor_freq, floor_count) are expected
only when X86_FEATURE_CPPC_PERF_PRIO is present.
Compare these independent expectations against the live driver's attr
array, catching bugs such as attributes leaking into wrong modes or
visibility functions checking incorrect conditions.
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate-ut.c | 139 ++++++++++++++++++++++++++++++--
drivers/cpufreq/amd-pstate.c | 8 ++
drivers/cpufreq/amd-pstate.h | 4 +
3 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 35e453a49c0f..5d87fb8a26df 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -23,6 +23,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitfield.h>
+#include <linux/cpufeature.h>
+#include <linux/cpufreq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -53,13 +55,15 @@ static int amd_pstate_ut_check_enabled(u32 index);
static int amd_pstate_ut_check_perf(u32 index);
static int amd_pstate_ut_check_freq(u32 index);
static int amd_pstate_ut_check_driver(u32 index);
+static int amd_pstate_ut_check_freq_attrs(u32 index);
static struct amd_pstate_ut_struct amd_pstate_ut_cases[] = {
- {"amd_pstate_ut_acpi_cpc_valid", amd_pstate_ut_acpi_cpc_valid },
- {"amd_pstate_ut_check_enabled", amd_pstate_ut_check_enabled },
- {"amd_pstate_ut_check_perf", amd_pstate_ut_check_perf },
- {"amd_pstate_ut_check_freq", amd_pstate_ut_check_freq },
- {"amd_pstate_ut_check_driver", amd_pstate_ut_check_driver }
+ {"amd_pstate_ut_acpi_cpc_valid", amd_pstate_ut_acpi_cpc_valid },
+ {"amd_pstate_ut_check_enabled", amd_pstate_ut_check_enabled },
+ {"amd_pstate_ut_check_perf", amd_pstate_ut_check_perf },
+ {"amd_pstate_ut_check_freq", amd_pstate_ut_check_freq },
+ {"amd_pstate_ut_check_driver", amd_pstate_ut_check_driver },
+ {"amd_pstate_ut_check_freq_attrs", amd_pstate_ut_check_freq_attrs },
};
static bool get_shared_mem(void)
@@ -274,6 +278,131 @@ static int amd_pstate_ut_check_driver(u32 index)
return ret;
}
+enum attr_category {
+ ATTR_ALWAYS,
+ ATTR_PREFCORE,
+ ATTR_EPP,
+ ATTR_FLOOR_FREQ,
+};
+
+static const struct {
+ const char *name;
+ enum attr_category category;
+} expected_freq_attrs[] = {
+ {"amd_pstate_max_freq", ATTR_ALWAYS},
+ {"amd_pstate_lowest_nonlinear_freq", ATTR_ALWAYS},
+ {"amd_pstate_highest_perf", ATTR_ALWAYS},
+ {"amd_pstate_prefcore_ranking", ATTR_PREFCORE},
+ {"amd_pstate_hw_prefcore", ATTR_PREFCORE},
+ {"energy_performance_preference", ATTR_EPP},
+ {"energy_performance_available_preferences", ATTR_EPP},
+ {"amd_pstate_floor_freq", ATTR_FLOOR_FREQ},
+ {"amd_pstate_floor_count", ATTR_FLOOR_FREQ},
+};
+
+static bool attr_in_driver(struct freq_attr **driver_attrs, const char *name)
+{
+ int j;
+
+ for (j = 0; driver_attrs[j]; j++) {
+ if (!strcmp(driver_attrs[j]->attr.name, name))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Verify that for each mode the driver's live ->attr array contains exactly
+ * the attributes that should be visible. Expected visibility is derived
+ * independently from hw_prefcore, cpu features, and the current mode —
+ * not from the driver's own visibility functions.
+ */
+static int amd_pstate_ut_check_freq_attrs(u32 index)
+{
+ enum amd_pstate_mode orig_mode = amd_pstate_get_status();
+ static const enum amd_pstate_mode modes[] = {
+ AMD_PSTATE_PASSIVE, AMD_PSTATE_ACTIVE, AMD_PSTATE_GUIDED,
+ };
+ bool has_prefcore, has_floor_freq;
+ int m, i, ret;
+
+ has_floor_freq = cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO);
+
+ /*
+ * Determine prefcore support from any online CPU's cpudata.
+ * hw_prefcore reflects the platform-wide decision made at init.
+ */
+ has_prefcore = false;
+ for_each_online_cpu(i) {
+ struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL;
+ struct amd_cpudata *cpudata;
+
+ policy = cpufreq_cpu_get(i);
+ if (!policy)
+ continue;
+ cpudata = policy->driver_data;
+ has_prefcore = cpudata->hw_prefcore;
+ break;
+ }
+
+ for (m = 0; m < ARRAY_SIZE(modes); m++) {
+ struct freq_attr **driver_attrs;
+
+ ret = amd_pstate_set_mode(modes[m]);
+ if (ret)
+ goto out;
+
+ driver_attrs = amd_pstate_get_current_attrs();
+ if (!driver_attrs) {
+ pr_err("%s: no driver attrs in mode %s\n",
+ __func__, amd_pstate_get_mode_string(modes[m]));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(expected_freq_attrs); i++) {
+ bool expected, found;
+
+ switch (expected_freq_attrs[i].category) {
+ case ATTR_ALWAYS:
+ expected = true;
+ break;
+ case ATTR_PREFCORE:
+ expected = has_prefcore;
+ break;
+ case ATTR_EPP:
+ expected = (modes[m] == AMD_PSTATE_ACTIVE);
+ break;
+ case ATTR_FLOOR_FREQ:
+ expected = has_floor_freq;
+ break;
+ default:
+ expected = false;
+ break;
+ }
+
+ found = attr_in_driver(driver_attrs,
+ expected_freq_attrs[i].name);
+
+ if (expected != found) {
+ pr_err("%s: mode %s: attr %s expected %s but is %s\n",
+ __func__,
+ amd_pstate_get_mode_string(modes[m]),
+ expected_freq_attrs[i].name,
+ expected ? "visible" : "hidden",
+ found ? "visible" : "hidden");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+ }
+
+ ret = 0;
+out:
+ amd_pstate_set_mode(orig_mode);
+ return ret;
+}
+
static int __init amd_pstate_ut_init(void)
{
u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 5eae74a67aeb..ed9fd4155a25 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1390,6 +1390,14 @@ static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
{&amd_pstate_floor_count, floor_freq_visibility},
};
+struct freq_attr **amd_pstate_get_current_attrs(void)
+{
+ if (!current_pstate_driver)
+ return NULL;
+ return current_pstate_driver->attr;
+}
+EXPORT_SYMBOL_GPL(amd_pstate_get_current_attrs);
+
static struct freq_attr **get_freq_attrs(void)
{
bool attr_visible[ARRAY_SIZE(amd_pstate_attr_visibility)];
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index 2f7a96836fcd..6551f559edf1 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -132,4 +132,8 @@ const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode);
int amd_pstate_get_status(void);
int amd_pstate_update_status(const char *buf, size_t size);
+struct freq_attr;
+
+struct freq_attr **amd_pstate_get_current_attrs(void);
+
#endif /* _LINUX_AMD_PSTATE_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (8 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking " Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count} Gautham R. Shenoy
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Jonathan Corbet,
Shuah Khan, Mario Limonciello
Add the missing amd_pstate_hw_prefcore filenames in the sysfs listing
example leading to the descriptions of these parameters. Clarify when
will the file be visible.
Fixes: b96b82d1af7f ("cpufreq: amd-pstate: Add documentation for `amd_pstate_hw_prefcore`")
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
Documentation/admin-guide/pm/amd-pstate.rst | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index e1771f2225d5..b8c846cbf301 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -239,6 +239,7 @@ control its functionality at the system level. They are located in the
root@hr-test1:/home/ray# ls /sys/devices/system/cpu/cpufreq/policy0/*amd*
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_highest_perf
+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_hw_prefcore
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq
@@ -264,8 +265,9 @@ This attribute is read-only.
``amd_pstate_hw_prefcore``
-Whether the platform supports the preferred core feature and it has been
-enabled. This attribute is read-only.
+Whether the platform supports the preferred core feature and it has
+been enabled. This attribute is read-only. This file is only visible
+on platforms which support the preferred core feature.
``amd_pstate_prefcore_ranking``
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking sysfs file
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (9 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count} Gautham R. Shenoy
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Jonathan Corbet,
Shuah Khan, Mario Limonciello
Add the missing amd_pstate_prefcore_ranking filenames in the sysfs
listing example leading to the descriptions of these
parameters. Clarify when will the file be visible.
Fixes: 15a2b764ea7c ("amd-pstate: Add missing documentation for `amd_pstate_prefcore_ranking`")
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
Documentation/admin-guide/pm/amd-pstate.rst | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index b8c846cbf301..b31a478c28ba 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -242,6 +242,7 @@ control its functionality at the system level. They are located in the
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_hw_prefcore
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq
+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_prefcore_ranking
``amd_pstate_highest_perf / amd_pstate_max_freq``
@@ -273,7 +274,8 @@ on platforms which support the preferred core feature.
The performance ranking of the core. This number doesn't have any unit, but
larger numbers are preferred at the time of reading. This can change at
-runtime based on platform conditions. This attribute is read-only.
+runtime based on platform conditions. This attribute is read-only. This file
+is only visible on platforms which support the preferred core feature.
``energy_performance_available_preferences``
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count}
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
` (10 preceding siblings ...)
2026-03-20 14:43 ` [PATCH v3 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking " Gautham R. Shenoy
@ 2026-03-20 14:43 ` Gautham R. Shenoy
11 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-20 14:43 UTC (permalink / raw)
To: Mario Limonciello, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm, Gautham R. Shenoy, Jonathan Corbet,
Shuah Khan, Mario Limonciello
Add documentation for the sysfs files
/sys/devices/system/cpu/cpufreq/policy*/amd_pstate_floor_freq
and
/sys/devices/system/cpu/cpufreq/policy*/amd_pstate_floor_count.
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
Documentation/admin-guide/pm/amd-pstate.rst | 32 +++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index b31a478c28ba..d6c2f233ab23 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -242,6 +242,8 @@ control its functionality at the system level. They are located in the
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_hw_prefcore
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq
+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_floor_freq
+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_floor_count
/sys/devices/system/cpu/cpufreq/policy0/amd_pstate_prefcore_ranking
@@ -277,6 +279,36 @@ larger numbers are preferred at the time of reading. This can change at
runtime based on platform conditions. This attribute is read-only. This file
is only visible on platforms which support the preferred core feature.
+``amd_pstate_floor_freq``
+
+The floor frequency associated with each CPU. Userspace can write any
+value between ``cpuinfo_min_freq`` and ``scaling_max_freq`` into this
+file. When the system is under power or thermal constraints, the
+platform firmware will attempt to throttle the CPU frequency to the
+value specified in ``amd_pstate_floor_freq`` before throttling it
+further. This allows userspace to specify different floor frequencies
+to different CPUs. For optimal results, threads of the same core
+should have the same floor frequency value. This file is only visible
+on platforms that support the CPPC Performance Priority feature.
+
+
+``amd_pstate_floor_count``
+
+The number of distinct Floor Performance levels supported by the
+platform. For example, if this value is 2, then the number of unique
+values obtained from the command ``cat
+/sys/devices/system/cpu/cpufreq/policy*/amd_pstate_floor_freq |
+sort -n | uniq`` should be at most this number for the behavior
+described in ``amd_pstate_floor_freq`` to take effect. A zero value
+implies that the platform supports unlimited floor performance levels.
+This file is only visible on platforms that support the CPPC
+Performance Priority feature.
+
+**Note**: When ``amd_pstate_floor_count`` is non-zero, the frequency to
+which the CPU is throttled under power or thermal constraints is
+undefined when the number of unique values of ``amd_pstate_floor_freq``
+across all CPUs in the system exceeds ``amd_pstate_floor_count``.
+
``energy_performance_available_preferences``
A list of all the supported EPP preferences that could be used for
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-20 14:43 ` [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase Gautham R. Shenoy
@ 2026-03-23 20:21 ` Mario Limonciello (AMD) (kernel.org)
2026-03-24 4:29 ` Gautham R. Shenoy
0 siblings, 1 reply; 24+ messages in thread
From: Mario Limonciello (AMD) (kernel.org) @ 2026-03-23 20:21 UTC (permalink / raw)
To: Gautham R. Shenoy, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm
On 3/20/2026 9:43 AM, Gautham R. Shenoy wrote:
> Currently when amd-pstate-ut test module is loaded, it runs all the
> tests from amd_pstate_ut_cases[] array.
>
> Add a module parameter named "run_only" that allows users to run a
> single test from the array by specifying the test name string.
>
> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> ---
> drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> index 447b9aa5ce40..35e453a49c0f 100644
> --- a/drivers/cpufreq/amd-pstate-ut.c
> +++ b/drivers/cpufreq/amd-pstate-ut.c
> @@ -35,6 +35,10 @@
>
> #include "amd-pstate.h"
>
> +static char *run_only;
> +module_param(run_only, charp, 0444);
> +MODULE_PARM_DESC(run_only,
> + "Run only the named test case (default: run all)");
This default shows the end effect; but it doesn't make sense for this
parameter IMO.
How about instead if you had a semicolon delimitted list and then
defaulted an empty list to mean all tests? Something like this:
static char *test_list;
module_param(test_list, charp, 0444)
MODULE_PARM_DESC(test_list,
"Semicolon delimitted list of tests to run (empty means run all tests)");
>
> struct amd_pstate_ut_struct {
> const char *name;
> @@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
> u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
>
> for (i = 0; i < arr_size; i++) {
> - int ret = amd_pstate_ut_cases[i].func(i);
> + int ret;
> +
> + if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
> + continue;
> +
> + ret = amd_pstate_ut_cases[i].func(i);
If you take my suggestion then you would split this on semicolon or end
of string and then allow matching multiple.
>
> if (ret)
> pr_err("%-4d %-20s\t fail: %d!\n", i+1, amd_pstate_ut_cases[i].name, ret);
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-23 20:21 ` Mario Limonciello (AMD) (kernel.org)
@ 2026-03-24 4:29 ` Gautham R. Shenoy
2026-03-24 4:34 ` Mario Limonciello
2026-03-25 4:28 ` K Prateek Nayak
0 siblings, 2 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-24 4:29 UTC (permalink / raw)
To: Mario Limonciello (AMD) (kernel.org)
Cc: Rafael J . Wysocki, Viresh Kumar, K Prateek Nayak, linux-kernel,
linux-pm
Hello Mario,
On Mon, Mar 23, 2026 at 03:21:17PM -0500, Mario Limonciello (AMD) (kernel.org) wrote:
>
>
> On 3/20/2026 9:43 AM, Gautham R. Shenoy wrote:
> > Currently when amd-pstate-ut test module is loaded, it runs all the
> > tests from amd_pstate_ut_cases[] array.
> >
> > Add a module parameter named "run_only" that allows users to run a
> > single test from the array by specifying the test name string.
> >
> > Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> > ---
> > drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
> > 1 file changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> > index 447b9aa5ce40..35e453a49c0f 100644
> > --- a/drivers/cpufreq/amd-pstate-ut.c
> > +++ b/drivers/cpufreq/amd-pstate-ut.c
> > @@ -35,6 +35,10 @@
> > #include "amd-pstate.h"
> > +static char *run_only;
> > +module_param(run_only, charp, 0444);
> > +MODULE_PARM_DESC(run_only,
> > + "Run only the named test case (default: run all)");
>
> This default shows the end effect; but it doesn't make sense for this
> parameter IMO.
>
> How about instead if you had a semicolon delimitted list and then defaulted
> an empty list to mean all tests? Something like this:
>
> static char *test_list;
> module_param(test_list, charp, 0444)
> MODULE_PARM_DESC(test_list,
> "Semicolon delimitted list of tests to run (empty means run all tests)");
This makes sense.
>
> > struct amd_pstate_ut_struct {
> > const char *name;
> > @@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
> > u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
> > for (i = 0; i < arr_size; i++) {
> > - int ret = amd_pstate_ut_cases[i].func(i);
> > + int ret;
> > +
> > + if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
> > + continue;
> > +
> > + ret = amd_pstate_ut_cases[i].func(i);
>
> If you take my suggestion then you would split this on semicolon or end of
> string and then allow matching multiple.
How about something like the following (diff on top of this
patch. Will fold it in and post a v4 if this looks ok)
x8----------------------------------------x8---------------------------------------------x8
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 5d87fb8a26df..5ef22a77a9c5 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -37,10 +37,10 @@
#include "amd-pstate.h"
-static char *run_only;
-module_param(run_only, charp, 0444);
-MODULE_PARM_DESC(run_only,
- "Run only the named test case (default: run all)");
+static char *test_list;
+module_param(test_list, charp, 0444);
+MODULE_PARM_DESC(test_list,
+ "Semicolon-delimited list of tests to run (empty means run all tests)");
struct amd_pstate_ut_struct {
const char *name;
@@ -403,6 +403,26 @@ static int amd_pstate_ut_check_freq_attrs(u32 index)
return ret;
}
+static bool test_in_list(const char *list, const char *name)
+{
+ size_t name_len = strlen(name);
+ const char *p = list;
+
+ while (*p) {
+ const char *sep = strchr(p, ';');
+ size_t token_len = sep ? sep - p : strlen(p);
+
+ if (token_len == name_len && !strncmp(p, name, token_len))
+ return true;
+
+ if (!sep)
+ break;
+ p = sep + 1;
+ }
+
+ return false;
+}
+
static int __init amd_pstate_ut_init(void)
{
u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
@@ -410,7 +430,8 @@ static int __init amd_pstate_ut_init(void)
for (i = 0; i < arr_size; i++) {
int ret;
- if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
+ if (test_list && *test_list &&
+ !test_in_list(test_list, amd_pstate_ut_cases[i].name))
continue;
ret = amd_pstate_ut_cases[i].func(i);
x8----------------------------------------x8---------------------------------------------x8
--
Thanks and Regards
gautham.
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-24 4:29 ` Gautham R. Shenoy
@ 2026-03-24 4:34 ` Mario Limonciello
2026-03-25 4:28 ` K Prateek Nayak
1 sibling, 0 replies; 24+ messages in thread
From: Mario Limonciello @ 2026-03-24 4:34 UTC (permalink / raw)
To: Gautham R. Shenoy
Cc: Rafael J . Wysocki, Viresh Kumar, K Prateek Nayak, linux-kernel,
linux-pm
On 3/23/26 11:29 PM, Gautham R. Shenoy wrote:
> Hello Mario,
>
> On Mon, Mar 23, 2026 at 03:21:17PM -0500, Mario Limonciello (AMD) (kernel.org) wrote:
>>
>>
>> On 3/20/2026 9:43 AM, Gautham R. Shenoy wrote:
>>> Currently when amd-pstate-ut test module is loaded, it runs all the
>>> tests from amd_pstate_ut_cases[] array.
>>>
>>> Add a module parameter named "run_only" that allows users to run a
>>> single test from the array by specifying the test name string.
>>>
>>> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
>>> ---
>>> drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
>>> 1 file changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
>>> index 447b9aa5ce40..35e453a49c0f 100644
>>> --- a/drivers/cpufreq/amd-pstate-ut.c
>>> +++ b/drivers/cpufreq/amd-pstate-ut.c
>>> @@ -35,6 +35,10 @@
>>> #include "amd-pstate.h"
>>> +static char *run_only;
>>> +module_param(run_only, charp, 0444);
>>> +MODULE_PARM_DESC(run_only,
>>> + "Run only the named test case (default: run all)");
>>
>> This default shows the end effect; but it doesn't make sense for this
>> parameter IMO.
>>
>> How about instead if you had a semicolon delimitted list and then defaulted
>> an empty list to mean all tests? Something like this:
>>
>> static char *test_list;
>> module_param(test_list, charp, 0444)
>> MODULE_PARM_DESC(test_list,
>> "Semicolon delimitted list of tests to run (empty means run all tests)");
>
>
> This makes sense.
>
>>
>>> struct amd_pstate_ut_struct {
>>> const char *name;
>>> @@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
>>> u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
>>> for (i = 0; i < arr_size; i++) {
>>> - int ret = amd_pstate_ut_cases[i].func(i);
>>> + int ret;
>>> +
>>> + if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
>>> + continue;
>>> +
>>> + ret = amd_pstate_ut_cases[i].func(i);
>>
>> If you take my suggestion then you would split this on semicolon or end of
>> string and then allow matching multiple.
>
> How about something like the following (diff on top of this
> patch. Will fold it in and post a v4 if this looks ok)
Yeah that's good.
>
> x8----------------------------------------x8---------------------------------------------x8
> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> index 5d87fb8a26df..5ef22a77a9c5 100644
> --- a/drivers/cpufreq/amd-pstate-ut.c
> +++ b/drivers/cpufreq/amd-pstate-ut.c
> @@ -37,10 +37,10 @@
>
> #include "amd-pstate.h"
>
> -static char *run_only;
> -module_param(run_only, charp, 0444);
> -MODULE_PARM_DESC(run_only,
> - "Run only the named test case (default: run all)");
> +static char *test_list;
> +module_param(test_list, charp, 0444);
> +MODULE_PARM_DESC(test_list,
> + "Semicolon-delimited list of tests to run (empty means run all tests)");
>
> struct amd_pstate_ut_struct {
> const char *name;
> @@ -403,6 +403,26 @@ static int amd_pstate_ut_check_freq_attrs(u32 index)
> return ret;
> }
>
> +static bool test_in_list(const char *list, const char *name)
> +{
> + size_t name_len = strlen(name);
> + const char *p = list;
> +
> + while (*p) {
> + const char *sep = strchr(p, ';');
> + size_t token_len = sep ? sep - p : strlen(p);
> +
> + if (token_len == name_len && !strncmp(p, name, token_len))
> + return true;
> +
> + if (!sep)
> + break;
> + p = sep + 1;
> + }
> +
> + return false;
> +}
> +
> static int __init amd_pstate_ut_init(void)
> {
> u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
> @@ -410,7 +430,8 @@ static int __init amd_pstate_ut_init(void)
> for (i = 0; i < arr_size; i++) {
> int ret;
>
> - if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
> + if (test_list && *test_list &&
> + !test_in_list(test_list, amd_pstate_ut_cases[i].name))
> continue;
>
> ret = amd_pstate_ut_cases[i].func(i);
> x8----------------------------------------x8---------------------------------------------x8
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
2026-03-20 14:43 ` [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
@ 2026-03-24 21:38 ` Mario Limonciello
2026-03-25 4:09 ` K Prateek Nayak
2026-03-26 11:30 ` Gautham R. Shenoy
0 siblings, 2 replies; 24+ messages in thread
From: Mario Limonciello @ 2026-03-24 21:38 UTC (permalink / raw)
To: Gautham R. Shenoy, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm
On 3/20/26 09:43, Gautham R. Shenoy wrote:
> Some future AMD processors have feature named "CPPC Performance
> Priority" which lets userspace specify different floor performance
> levels for different CPUs. The platform firmware takes these different
> floor performance levels into consideration while throttling the CPUs
> under power/thermal constraints. The presence of this feature is
> indicated by bit 16 of the EDX register for CPUID leaf
> 0x80000007. More details can be found in AMD Publication titled "AMD64
> Collaborative Processor Performance Control (CPPC) Performance
> Priority" Revision 1.10.
>
> The number of distinct floor performance levels supported on the
> platform will be advertised through the bits 32:39 of the
> MSR_AMD_CPPC_CAP1. Bits 0:7 of a new MSR MSR_AMD_CPPC_REQ2
> (0xc00102b5) will be used to specify the desired floor performance
> level for that CPU.
>
> Add support for the aforementioned MSR_AMD_CPPC_REQ2, and macros for
> parsing and updating the relevant bits from MSR_AMD_CPPC_CAP1 and
> MSR_AMD_CPPC_REQ2.
>
> On boot if the default value of the MSR_AMD_CPPC_REQ2[7:0] (Floor
> Perf) is lower than CPPC.lowest_perf, and thus invalid, initialize it
> to MSR_AMD_CPPC_CAP1.nominal_perf which is a sane default value.
>
> Save the boot-time floor_perf during amd_pstate_init_floor_perf(). In
> a subsequent patch it will be restored in the suspend, offline, and
> exit paths, mirroring how bios_min_perf is handled for
> MSR_AMD_CPPC_REQ.
>
> Link: https://docs.amd.com/v/u/en-US/69206_1.10_AMD64_CPPC_PUB
> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> ---
> arch/x86/include/asm/msr-index.h | 5 ++
> drivers/cpufreq/amd-pstate.c | 78 +++++++++++++++++++++++++++++++-
> drivers/cpufreq/amd-pstate.h | 6 +++
> 3 files changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 6673601246b3..e126c7fb69cf 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -765,12 +765,14 @@
> #define MSR_AMD_CPPC_CAP2 0xc00102b2
> #define MSR_AMD_CPPC_REQ 0xc00102b3
> #define MSR_AMD_CPPC_STATUS 0xc00102b4
> +#define MSR_AMD_CPPC_REQ2 0xc00102b5
>
> /* Masks for use with MSR_AMD_CPPC_CAP1 */
> #define AMD_CPPC_LOWEST_PERF_MASK GENMASK(7, 0)
> #define AMD_CPPC_LOWNONLIN_PERF_MASK GENMASK(15, 8)
> #define AMD_CPPC_NOMINAL_PERF_MASK GENMASK(23, 16)
> #define AMD_CPPC_HIGHEST_PERF_MASK GENMASK(31, 24)
> +#define AMD_CPPC_FLOOR_PERF_CNT_MASK GENMASK_ULL(39, 32)
>
> /* Masks for use with MSR_AMD_CPPC_REQ */
> #define AMD_CPPC_MAX_PERF_MASK GENMASK(7, 0)
> @@ -778,6 +780,9 @@
> #define AMD_CPPC_DES_PERF_MASK GENMASK(23, 16)
> #define AMD_CPPC_EPP_PERF_MASK GENMASK(31, 24)
>
> +/* Masks for use with MSR_AMD_CPPC_REQ2 */
> +#define AMD_CPPC_FLOOR_PERF_MASK GENMASK(7, 0)
> +
> /* AMD Performance Counter Global Status and Control MSRs */
> #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300
> #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 4de2037a414c..53b8173ff183 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -329,6 +329,65 @@ static inline int amd_pstate_set_epp(struct cpufreq_policy *policy, u8 epp)
> return static_call(amd_pstate_set_epp)(policy, epp);
> }
>
> +static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
> +{
> + struct amd_cpudata *cpudata = policy->driver_data;
> + u64 value, prev;
> + int ret;
> +
> + if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
> + return 0;
> +
> + value = prev = READ_ONCE(cpudata->cppc_req2_cached);
> + FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);
> +
> + if (value == prev)
> + return 0;
> +
> + ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
> + if (ret) {
> + pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
> + return ret;
> + }
> +
> + WRITE_ONCE(cpudata->cppc_req2_cached, value);
> +
> + return ret;
> +}
> +
> +static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
> +{
> + struct amd_cpudata *cpudata = policy->driver_data;
> + u8 floor_perf;
> + u64 value;
> + int ret;
> +
> + if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
> + return 0;
> +
> + ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, &value);
> + if (ret) {
> + pr_err("failed to read CPPC REQ2 value. Error (%d)\n", ret);
> + return ret;
> + }
> +
> + WRITE_ONCE(cpudata->cppc_req2_cached, value);
> + floor_perf = FIELD_GET(AMD_CPPC_FLOOR_PERF_MASK,
> + cpudata->cppc_req2_cached);
> +
> + /* Set a sane value for floor_perf if the default value is invalid */
> + if (floor_perf < cpudata->perf.lowest_perf) {
> + floor_perf = cpudata->perf.nominal_perf;
> + ret = amd_pstate_set_floor_perf(policy, floor_perf);
> + if (ret)
> + return ret;
> + }
> +
> + cpudata->bios_floor_perf = floor_perf;
> +
> + return 0;
> +}
> +
> static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
> {
> struct amd_cpudata *cpudata = policy->driver_data;
> @@ -426,6 +485,7 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
> perf.lowest_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
> WRITE_ONCE(cpudata->perf, perf);
> WRITE_ONCE(cpudata->prefcore_ranking, FIELD_GET(AMD_CPPC_HIGHEST_PERF_MASK, cap1));
> + WRITE_ONCE(cpudata->floor_perf_cnt, FIELD_GET(AMD_CPPC_FLOOR_PERF_CNT_MASK, cap1));
>
> return 0;
> }
> @@ -1024,6 +1084,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
> cpudata->nominal_freq,
> perf.highest_perf);
>
> + policy->driver_data = cpudata;
> ret = amd_pstate_cppc_enable(policy);
> if (ret)
> goto free_cpudata1;
> @@ -1036,6 +1097,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
> if (cpu_feature_enabled(X86_FEATURE_CPPC))
> policy->fast_switch_possible = true;
>
> + ret = amd_pstate_init_floor_perf(policy);
> + if (ret) {
> + dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
> + goto free_cpudata1;
> + }
> +
> ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
> FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
> if (ret < 0) {
> @@ -1050,7 +1117,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
> goto free_cpudata2;
> }
>
> - policy->driver_data = cpudata;
>
> if (!current_pstate_driver->adjust_perf)
> current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
> @@ -1062,6 +1128,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
> free_cpudata1:
> pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
> kfree(cpudata);
> + policy->driver_data = NULL;
> return ret;
> }
>
> @@ -1072,6 +1139,7 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
>
> /* Reset CPPC_REQ MSR to the BIOS value */
> amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
> + amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
>
> freq_qos_remove_request(&cpudata->req[1]);
> freq_qos_remove_request(&cpudata->req[0]);
> @@ -1598,6 +1666,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
> if (ret)
> goto free_cpudata1;
>
> + ret = amd_pstate_init_floor_perf(policy);
> + if (ret) {
> + dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
> + goto free_cpudata1;
> + }
> +
> current_pstate_driver->adjust_perf = NULL;
>
> return 0;
> @@ -1605,6 +1679,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
> free_cpudata1:
> pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
> kfree(cpudata);
> + policy->driver_data = NULL;
> return ret;
> }
>
> @@ -1617,6 +1692,7 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
>
> /* Reset CPPC_REQ MSR to the BIOS value */
> amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
> + amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
>
> kfree(cpudata);
> policy->driver_data = NULL;
> diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
> index cb45fdca27a6..f04561da4518 100644
> --- a/drivers/cpufreq/amd-pstate.h
> +++ b/drivers/cpufreq/amd-pstate.h
> @@ -62,9 +62,12 @@ struct amd_aperf_mperf {
> * @cpu: CPU number
> * @req: constraint request to apply
> * @cppc_req_cached: cached performance request hints
> + * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
> * @perf: cached performance-related data
> * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
> * priority.
> + * @floor_perf_cnt: Cached value of the number of distinct floor
> + * performance levels supported
> * @min_limit_freq: Cached value of policy->min (in khz)
> * @max_limit_freq: Cached value of policy->max (in khz)
> * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
> @@ -87,10 +90,13 @@ struct amd_cpudata {
>
> struct freq_qos_request req[2];
> u64 cppc_req_cached;
> + u64 cppc_req2_cached;
>
> union perf_cached perf;
>
> u8 prefcore_ranking;
> + u8 floor_perf_cnt;
> + u8 bios_floor_perf;
It looks like you forgot to update doc for bios_floor_perf
> u32 min_limit_freq;
> u32 max_limit_freq;
> u32 nominal_freq;
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count
2026-03-20 14:43 ` [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
@ 2026-03-24 21:39 ` Mario Limonciello
0 siblings, 0 replies; 24+ messages in thread
From: Mario Limonciello @ 2026-03-24 21:39 UTC (permalink / raw)
To: Gautham R. Shenoy, Rafael J . Wysocki, Viresh Kumar,
K Prateek Nayak
Cc: linux-kernel, linux-pm
On 3/20/26 09:43, Gautham R. Shenoy wrote:
> When Floor Performance feature is supported by the platform, expose
> two sysfs files:
>
> * amd_pstate_floor_freq to allow userspace to request the floor
> frequency for each CPU.
>
> * amd_pstate_floor_count which advertises the number of distinct
> levels of floor frequencies supported on this platform.
>
> Reset the floor_perf to bios_floor_perf in the suspend, offline, and
> exit paths, and restore the value to the cached user-request
> floor_freq on the resume and online paths mirroring how bios_min_perf
> is handled for MSR_AMD_CPPC_REQ.
>
> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> ---
> drivers/cpufreq/amd-pstate.c | 93 +++++++++++++++++++++++++++++++++---
> drivers/cpufreq/amd-pstate.h | 2 +
> 2 files changed, 89 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 53b8173ff183..a068c4457a8f 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -383,8 +383,10 @@ static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
> return ret;
> }
>
> - cpudata->bios_floor_perf = floor_perf;
>
> + cpudata->bios_floor_perf = floor_perf;
Double check the whitespace between 5 and 6; I wouldn't expect this line
to ping pong.
> + cpudata->floor_freq = perf_to_freq(cpudata->perf, cpudata->nominal_freq,
> + floor_perf);
> return 0;
> }
>
> @@ -1288,6 +1290,46 @@ static ssize_t show_energy_performance_preference(
> return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
> }
>
> +static ssize_t store_amd_pstate_floor_freq(struct cpufreq_policy *policy,
> + const char *buf, size_t count)
> +{
> + struct amd_cpudata *cpudata = policy->driver_data;
> + union perf_cached perf = READ_ONCE(cpudata->perf);
> + unsigned int freq;
> + u8 floor_perf;
> + int ret;
> +
> + ret = kstrtouint(buf, 0, &freq);
> + if (ret)
> + return ret;
> +
> + if (freq < policy->cpuinfo.min_freq || freq > policy->max)
> + return -EINVAL;
> +
> + floor_perf = freq_to_perf(perf, cpudata->nominal_freq, freq);
> + ret = amd_pstate_set_floor_perf(policy, floor_perf);
> +
> + if (!ret)
> + cpudata->floor_freq = freq;
> +
> + return ret ?: count;
> +}
> +
> +static ssize_t show_amd_pstate_floor_freq(struct cpufreq_policy *policy, char *buf)
> +{
> + struct amd_cpudata *cpudata = policy->driver_data;
> +
> + return sysfs_emit(buf, "%u\n", cpudata->floor_freq);
> +}
> +
> +static ssize_t show_amd_pstate_floor_count(struct cpufreq_policy *policy, char *buf)
> +{
> + struct amd_cpudata *cpudata = policy->driver_data;
> + u8 count = cpudata->floor_perf_cnt;
> +
> + return sysfs_emit(buf, "%u\n", count);
> +}
> +
> cpufreq_freq_attr_ro(amd_pstate_max_freq);
> cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
>
> @@ -1296,6 +1338,8 @@ cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
> cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
> cpufreq_freq_attr_rw(energy_performance_preference);
> cpufreq_freq_attr_ro(energy_performance_available_preferences);
> +cpufreq_freq_attr_rw(amd_pstate_floor_freq);
> +cpufreq_freq_attr_ro(amd_pstate_floor_count);
>
> struct freq_attr_visibility {
> struct freq_attr *attr;
> @@ -1320,6 +1364,12 @@ static bool epp_visibility(void)
> return cppc_state == AMD_PSTATE_ACTIVE;
> }
>
> +/* Determines whether amd_pstate_floor_freq related attributes should be visible */
> +static bool floor_freq_visibility(void)
> +{
> + return cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO);
> +}
> +
> static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
> {&amd_pstate_max_freq, always_visible},
> {&amd_pstate_lowest_nonlinear_freq, always_visible},
> @@ -1328,6 +1378,8 @@ static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
> {&amd_pstate_hw_prefcore, prefcore_visibility},
> {&energy_performance_preference, epp_visibility},
> {&energy_performance_available_preferences, epp_visibility},
> + {&amd_pstate_floor_freq, floor_freq_visibility},
> + {&amd_pstate_floor_count, floor_freq_visibility},
> };
>
> static struct freq_attr **get_freq_attrs(void)
> @@ -1748,24 +1800,39 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
>
> static int amd_pstate_cpu_online(struct cpufreq_policy *policy)
> {
> - return amd_pstate_cppc_enable(policy);
> + struct amd_cpudata *cpudata = policy->driver_data;
> + union perf_cached perf = READ_ONCE(cpudata->perf);
> + u8 cached_floor_perf;
> + int ret;
> +
> + ret = amd_pstate_cppc_enable(policy);
> + if (ret)
> + return ret;
> +
> + cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
> + return amd_pstate_set_floor_perf(policy, cached_floor_perf);
> }
>
> static int amd_pstate_cpu_offline(struct cpufreq_policy *policy)
> {
> struct amd_cpudata *cpudata = policy->driver_data;
> union perf_cached perf = READ_ONCE(cpudata->perf);
> + int ret;
>
> /*
> * Reset CPPC_REQ MSR to the BIOS value, this will allow us to retain the BIOS specified
> * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the
> * limits, epp and desired perf will get reset to the cached values in cpudata struct
> */
> - return amd_pstate_update_perf(policy, perf.bios_min_perf,
> + ret = amd_pstate_update_perf(policy, perf.bios_min_perf,
> FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached),
> FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached),
> FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached),
> false);
> + if (ret)
> + return ret;
> +
> + return amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
> }
>
> static int amd_pstate_suspend(struct cpufreq_policy *policy)
> @@ -1787,6 +1854,10 @@ static int amd_pstate_suspend(struct cpufreq_policy *policy)
> if (ret)
> return ret;
>
> + ret = amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
> + if (ret)
> + return ret;
> +
> /* set this flag to avoid setting core offline*/
> cpudata->suspended = true;
>
> @@ -1798,15 +1869,24 @@ static int amd_pstate_resume(struct cpufreq_policy *policy)
> struct amd_cpudata *cpudata = policy->driver_data;
> union perf_cached perf = READ_ONCE(cpudata->perf);
> int cur_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->cur);
> + u8 cached_floor_perf;
> + int ret;
>
> /* Set CPPC_REQ to last sane value until the governor updates it */
> - return amd_pstate_update_perf(policy, perf.min_limit_perf, cur_perf, perf.max_limit_perf,
> - 0U, false);
> + ret = amd_pstate_update_perf(policy, perf.min_limit_perf, cur_perf, perf.max_limit_perf,
> + 0U, false);
> + if (ret)
> + return ret;
> +
> + cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
> + return amd_pstate_set_floor_perf(policy, cached_floor_perf);
> }
>
> static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
> {
> struct amd_cpudata *cpudata = policy->driver_data;
> + union perf_cached perf = READ_ONCE(cpudata->perf);
> + u8 cached_floor_perf;
>
> if (cpudata->suspended) {
> int ret;
> @@ -1819,7 +1899,8 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy)
> cpudata->suspended = false;
> }
>
> - return 0;
> + cached_floor_perf = freq_to_perf(perf, cpudata->nominal_freq, cpudata->floor_freq);
> + return amd_pstate_set_floor_perf(policy, cached_floor_perf);
> }
>
> static struct cpufreq_driver amd_pstate_driver = {
> diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
> index f04561da4518..2f7a96836fcd 100644
> --- a/drivers/cpufreq/amd-pstate.h
> +++ b/drivers/cpufreq/amd-pstate.h
> @@ -72,6 +72,7 @@ struct amd_aperf_mperf {
> * @max_limit_freq: Cached value of policy->max (in khz)
> * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
> * @lowest_nonlinear_freq: the frequency (in khz) that mapped to lowest_nonlinear_perf
> + * @floor_freq: Cached value of the user requested floor_freq
> * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
> * @prev: Last Aperf/Mperf/tsc count value read from register
> * @freq: current cpu frequency value (in khz)
> @@ -101,6 +102,7 @@ struct amd_cpudata {
> u32 max_limit_freq;
> u32 nominal_freq;
> u32 lowest_nonlinear_freq;
> + u32 floor_freq;
>
> struct amd_aperf_mperf cur;
> struct amd_aperf_mperf prev;
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
2026-03-24 21:38 ` Mario Limonciello
@ 2026-03-25 4:09 ` K Prateek Nayak
2026-03-25 4:18 ` K Prateek Nayak
2026-03-26 11:30 ` Gautham R. Shenoy
1 sibling, 1 reply; 24+ messages in thread
From: K Prateek Nayak @ 2026-03-25 4:09 UTC (permalink / raw)
To: Mario Limonciello, Gautham R. Shenoy, Rafael J . Wysocki,
Viresh Kumar
Cc: linux-kernel, linux-pm
Hello Mario,
On 3/25/2026 3:08 AM, Mario Limonciello wrote:
>> * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
>> @@ -87,10 +90,13 @@ struct amd_cpudata {
>> struct freq_qos_request req[2];
>> u64 cppc_req_cached;
>> + u64 cppc_req2_cached;
>> union perf_cached perf;
>> u8 prefcore_ranking;
>> + u8 floor_perf_cnt;
>> + u8 bios_floor_perf;
>
> It looks like you forgot to update doc for bios_floor_perf
"bios_floor_perf" is an internal detail that caches the initial state of
"FloorPerf" from CPPC_REQ2 when the driver is loaded.
It is only used to restore the FloorPerf to the original when the CPU is
offlined, the driver unloaded, or when the CPU is suspended. This
essentially resets the state of the CPU to what it was at the boot so a
kexec, driver switch can start off afresh from the BIOS defaults.
User can read amd_pstate_floor_freq just after the boot to know what the
default is. Do we really need to expose this?
>
>> u32 min_limit_freq;
>> u32 max_limit_freq;
>> u32 nominal_freq;
>
--
Thanks and Regards,
Prateek
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
2026-03-25 4:09 ` K Prateek Nayak
@ 2026-03-25 4:18 ` K Prateek Nayak
0 siblings, 0 replies; 24+ messages in thread
From: K Prateek Nayak @ 2026-03-25 4:18 UTC (permalink / raw)
To: Mario Limonciello, Gautham R. Shenoy, Rafael J . Wysocki,
Viresh Kumar
Cc: linux-kernel, linux-pm
On 3/25/2026 9:39 AM, K Prateek Nayak wrote:
> Hello Mario,
>
> On 3/25/2026 3:08 AM, Mario Limonciello wrote:
>>> * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
>>> @@ -87,10 +90,13 @@ struct amd_cpudata {
>>> struct freq_qos_request req[2];
>>> u64 cppc_req_cached;
>>> + u64 cppc_req2_cached;
>>> union perf_cached perf;
>>> u8 prefcore_ranking;
>>> + u8 floor_perf_cnt;
>>> + u8 bios_floor_perf;
>>
>> It looks like you forgot to update doc for bios_floor_perf
Me realizes you meant the comment above the stuct! Sorry for the noise.
_Me goes and grabs a coffee to wake myself up_
>
> "bios_floor_perf" is an internal detail that caches the initial state of
> "FloorPerf" from CPPC_REQ2 when the driver is loaded.
>
> It is only used to restore the FloorPerf to the original when the CPU is
> offlined, the driver unloaded, or when the CPU is suspended. This
> essentially resets the state of the CPU to what it was at the boot so a
> kexec, driver switch can start off afresh from the BIOS defaults.
>
> User can read amd_pstate_floor_freq just after the boot to know what the
> default is. Do we really need to expose this?
>
>>
>>> u32 min_limit_freq;
>>> u32 max_limit_freq;
>>> u32 nominal_freq;
>>
>
--
Thanks and Regards,
Prateek
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-24 4:29 ` Gautham R. Shenoy
2026-03-24 4:34 ` Mario Limonciello
@ 2026-03-25 4:28 ` K Prateek Nayak
2026-03-25 13:45 ` Mario Limonciello
1 sibling, 1 reply; 24+ messages in thread
From: K Prateek Nayak @ 2026-03-25 4:28 UTC (permalink / raw)
To: Gautham R. Shenoy, Mario Limonciello (AMD) (kernel.org)
Cc: Rafael J . Wysocki, Viresh Kumar, linux-kernel, linux-pm
Hello Gautham,
On 3/24/2026 9:59 AM, Gautham R. Shenoy wrote:
> +static bool test_in_list(const char *list, const char *name)
> +{
> + size_t name_len = strlen(name);
> + const char *p = list;
> +
> + while (*p) {
> + const char *sep = strchr(p, ';');
Any particular reason for using a ";" as the separator instead of ","?
I personally prefer "," because with ";", I need to explicitly add
'' around the test_list otherwise bash thinks the command ends at ";"
but with "," that is avoided.
Thoughts?
> + size_t token_len = sep ? sep - p : strlen(p);
> +
> + if (token_len == name_len && !strncmp(p, name, token_len))
> + return true;
> +
> + if (!sep)
> + break;
> + p = sep + 1;
> + }
> +
> + return false;
> +}
--
Thanks and Regards,
Prateek
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-25 4:28 ` K Prateek Nayak
@ 2026-03-25 13:45 ` Mario Limonciello
2026-03-26 11:29 ` Gautham R. Shenoy
0 siblings, 1 reply; 24+ messages in thread
From: Mario Limonciello @ 2026-03-25 13:45 UTC (permalink / raw)
To: K Prateek Nayak, Gautham R. Shenoy
Cc: Rafael J . Wysocki, Viresh Kumar, linux-kernel, linux-pm
On 3/24/26 23:28, K Prateek Nayak wrote:
> Hello Gautham,
>
> On 3/24/2026 9:59 AM, Gautham R. Shenoy wrote:
>> +static bool test_in_list(const char *list, const char *name)
>> +{
>> + size_t name_len = strlen(name);
>> + const char *p = list;
>> +
>> + while (*p) {
>> + const char *sep = strchr(p, ';');
>
> Any particular reason for using a ";" as the separator instead of ","?
>
> I personally prefer "," because with ";", I need to explicitly add
> '' around the test_list otherwise bash thinks the command ends at ";"
> but with "," that is avoided.
>
> Thoughts?
>
Sure, that sounds like a good reason to use a comma instead.
>> + size_t token_len = sep ? sep - p : strlen(p);
>> +
>> + if (token_len == name_len && !strncmp(p, name, token_len))
>> + return true;
>> +
>> + if (!sep)
>> + break;
>> + p = sep + 1;
>> + }
>> +
>> + return false;
>> +}
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
2026-03-25 13:45 ` Mario Limonciello
@ 2026-03-26 11:29 ` Gautham R. Shenoy
0 siblings, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-26 11:29 UTC (permalink / raw)
To: Mario Limonciello
Cc: K Prateek Nayak, Rafael J . Wysocki, Viresh Kumar, linux-kernel,
linux-pm
On Wed, Mar 25, 2026 at 08:45:05AM -0500, Mario Limonciello wrote:
>
>
> On 3/24/26 23:28, K Prateek Nayak wrote:
> > Hello Gautham,
> >
> > On 3/24/2026 9:59 AM, Gautham R. Shenoy wrote:
> > > +static bool test_in_list(const char *list, const char *name)
> > > +{
> > > + size_t name_len = strlen(name);
> > > + const char *p = list;
> > > +
> > > + while (*p) {
> > > + const char *sep = strchr(p, ';');
> >
> > Any particular reason for using a ";" as the separator instead of ","?
> >
> > I personally prefer "," because with ";", I need to explicitly add
> > '' around the test_list otherwise bash thinks the command ends at ";"
> > but with "," that is avoided.
> >
> > Thoughts?
> >
>
> Sure, that sounds like a good reason to use a comma instead.
Sure, I wil change it to a comma-separated list in v4.
--
Thanks and Regards
gautham.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
2026-03-24 21:38 ` Mario Limonciello
2026-03-25 4:09 ` K Prateek Nayak
@ 2026-03-26 11:30 ` Gautham R. Shenoy
1 sibling, 0 replies; 24+ messages in thread
From: Gautham R. Shenoy @ 2026-03-26 11:30 UTC (permalink / raw)
To: Mario Limonciello
Cc: Rafael J . Wysocki, Viresh Kumar, K Prateek Nayak, linux-kernel,
linux-pm
Hello Mario,
On Tue, Mar 24, 2026 at 04:38:07PM -0500, Mario Limonciello wrote:
>
>
[..snip..]
> > index cb45fdca27a6..f04561da4518 100644
> > --- a/drivers/cpufreq/amd-pstate.h
> > +++ b/drivers/cpufreq/amd-pstate.h
> > @@ -62,9 +62,12 @@ struct amd_aperf_mperf {
> > * @cpu: CPU number
> > * @req: constraint request to apply
> > * @cppc_req_cached: cached performance request hints
> > + * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
> > * @perf: cached performance-related data
> > * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
> > * priority.
> > + * @floor_perf_cnt: Cached value of the number of distinct floor
> > + * performance levels supported
> > * @min_limit_freq: Cached value of policy->min (in khz)
> > * @max_limit_freq: Cached value of policy->max (in khz)
> > * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
> > @@ -87,10 +90,13 @@ struct amd_cpudata {
> > struct freq_qos_request req[2];
> > u64 cppc_req_cached;
> > + u64 cppc_req2_cached;
> > union perf_cached perf;
> > u8 prefcore_ranking;
> > + u8 floor_perf_cnt;
> > + u8 bios_floor_perf;
>
> It looks like you forgot to update doc for bios_floor_perf
Thanks for catching this. I will add the doc for bios_floor_perf in v4.
--
Thanks and Regards
gautham.
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-03-26 11:30 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 02/12] amd-pstate: Update cppc_req_cached in fast_switch case Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 03/12] amd-pstate: Make certain freq_attrs conditionally visible Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
2026-03-24 21:38 ` Mario Limonciello
2026-03-25 4:09 ` K Prateek Nayak
2026-03-25 4:18 ` K Prateek Nayak
2026-03-26 11:30 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
2026-03-24 21:39 ` Mario Limonciello
2026-03-20 14:43 ` [PATCH v3 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2() Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase Gautham R. Shenoy
2026-03-23 20:21 ` Mario Limonciello (AMD) (kernel.org)
2026-03-24 4:29 ` Gautham R. Shenoy
2026-03-24 4:34 ` Mario Limonciello
2026-03-25 4:28 ` K Prateek Nayak
2026-03-25 13:45 ` Mario Limonciello
2026-03-26 11:29 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking " Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count} Gautham R. Shenoy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox