summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-05-20 22:03:41 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-05-20 22:03:41 +0200
commita67f3113331d9fb3eb0664602d9b581cb2df7294 (patch)
tree169ab98f163dbf64d8ed67ae4bcd63c55bf5117c
parent85cffdb21bc1a928f4c89f88dcdf42a460b04e70 (diff)
parente4e9b7b38d5db2cc6a8770bc0596bb8b36b92b1f (diff)
Merge tag 'amd-pstate-v7.1-2026-05-14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/superm1/linux into pm-cpufreq-fixes
Merge amd-pstate fixes for 7.1 (05/14/2026) from Mario Limonciello: "A number of fixes to the dynamic epp feature which was new to kernel 7.1, including making it opt in only." * tag 'amd-pstate-v7.1-2026-05-14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/superm1/linux: cpufreq/amd-pstate: Drop Kconfig option for dynamic EPP cpufreq/amd-pstate-ut: Drop policy reference before driver switch cpufreq/amd-pstate: Use "epp_default_dc" as default when dynamic_epp is disabled cpufreq/amd-pstate: Reorder notifier unregistration and floor perf reset cpufreq/amd-pstate: Allow writes to dynamic_epp when state isn't modified cpufreq/amd-pstate: Return -ENOMEM on failure to allocate profile_name cpufreq/amd-pstate: Grab "amd_pstate_driver_lock" when toggling dynamic_epp
-rw-r--r--Documentation/admin-guide/pm/amd-pstate.rst11
-rw-r--r--drivers/cpufreq/Kconfig.x8612
-rw-r--r--drivers/cpufreq/amd-pstate-ut.c36
-rw-r--r--drivers/cpufreq/amd-pstate.c27
4 files changed, 52 insertions, 34 deletions
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index f8e7050fc762..a95e2ebce005 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -358,9 +358,9 @@ Dynamic energy performance profile
The amd-pstate driver supports dynamically selecting the energy performance
profile based on whether the machine is running on AC or DC power.
-Whether this behavior is enabled by default depends on the kernel
-config option `CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`. This behavior can also be overridden
-at runtime by the sysfs file ``/sys/devices/system/cpu/cpufreq/policyX/dynamic_epp``.
+Whether this behavior is enabled by default depends on the kernel command line option
+``amd_dynamic_epp`` is set. This behavior can also be overridden
+at runtime by the sysfs file ``/sys/devices/system/cpu/amd_pstate/dynamic_epp``.
When set to enabled, the driver will select a different energy performance
profile when the machine is running on battery or AC power. The driver will
@@ -485,9 +485,8 @@ kernel parameter ``amd_prefcore=disable``.
``amd_dynamic_epp``
When AMD pstate is in auto mode, dynamic EPP will control whether the kernel
-autonomously changes the EPP mode. The default is configured by
-``CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP`` but can be explicitly enabled with
-``amd_dynamic_epp=enable`` or disabled with ``amd_dynamic_epp=disable``.
+autonomously changes the EPP mode. The default is disabled. It can be enabled
+with the kernel parameter ``amd_dynamic_epp=enable``.
User Space Interface in ``sysfs`` - General
===========================================
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 027e6ea2e038..a9093cd5e5d1 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -70,18 +70,6 @@ config X86_AMD_PSTATE_DEFAULT_MODE
For details, take a look at:
<file:Documentation/admin-guide/pm/amd-pstate.rst>.
-config X86_AMD_PSTATE_DYNAMIC_EPP
- bool "AMD Processor P-State dynamic EPP support"
- depends on X86_AMD_PSTATE
- default n
- help
- Allow the kernel to dynamically change the energy performance
- value from events like ACPI platform profile and AC adapter plug
- events.
-
- This feature can also be changed at runtime, this configuration
- option only sets the kernel default value behavior.
-
config X86_AMD_PSTATE_UT
tristate "selftest for AMD Processor P-State driver"
depends on X86 && ACPI_PROCESSOR
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index aa8a464fab47..13a23dac477d 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -274,20 +274,21 @@ static int amd_pstate_set_mode(enum amd_pstate_mode mode)
static int amd_pstate_ut_epp(u32 index)
{
- struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL;
- char *buf __free(cleanup_page) = NULL;
static const char * const epp_strings[] = {
- "performance",
- "balance_performance",
- "balance_power",
"power",
+ "balance_power",
+ "balance_performance",
+ "performance",
};
- struct amd_cpudata *cpudata;
+ char *buf __free(cleanup_page) = NULL;
+ struct cpufreq_policy *policy = NULL;
enum amd_pstate_mode orig_mode;
+ struct amd_cpudata *cpudata;
+ unsigned long orig_policy;
bool orig_dynamic_epp;
int ret, cpu = 0;
- int i;
u16 epp;
+ int i;
policy = cpufreq_cpu_get(cpu);
if (!policy)
@@ -297,6 +298,10 @@ static int amd_pstate_ut_epp(u32 index)
orig_mode = amd_pstate_get_status();
orig_dynamic_epp = cpudata->dynamic_epp;
+ /* Drop reference before potential driver change. */
+ cpufreq_cpu_put(policy);
+ policy = NULL;
+
/* disable dynamic EPP before running test */
if (cpudata->dynamic_epp) {
pr_debug("Dynamic EPP is enabled, disabling it\n");
@@ -311,6 +316,17 @@ static int amd_pstate_ut_epp(u32 index)
if (ret)
goto out;
+ policy = cpufreq_cpu_get(cpu);
+ if (!policy) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ down_write(&policy->rwsem);
+ cpudata = policy->driver_data;
+ orig_policy = cpudata->policy;
+ cpudata->policy = CPUFREQ_POLICY_POWERSAVE;
+
for (epp = 0; epp <= U8_MAX; epp++) {
u8 val;
@@ -358,6 +374,12 @@ static int amd_pstate_ut_epp(u32 index)
ret = 0;
out:
+ if (policy) {
+ cpudata->policy = orig_policy;
+ up_write(&policy->rwsem);
+ cpufreq_cpu_put(policy);
+ }
+
if (orig_dynamic_epp) {
int ret2;
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 453084c67327..62b5d995281d 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -87,11 +87,7 @@ static struct cpufreq_driver amd_pstate_driver;
static struct cpufreq_driver amd_pstate_epp_driver;
static int cppc_state = AMD_PSTATE_UNDEFINED;
static bool amd_pstate_prefcore = true;
-#ifdef CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP
-static bool dynamic_epp = CONFIG_X86_AMD_PSTATE_DYNAMIC_EPP;
-#else
static bool dynamic_epp;
-#endif
static struct quirk_entry *quirks;
/*
@@ -1291,6 +1287,8 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
return ret;
cpudata->profile_name = kasprintf(GFP_KERNEL, "amd-pstate-epp-cpu%d", cpudata->cpu);
+ if (!cpudata->profile_name)
+ return -ENOMEM;
cpudata->ppdev = platform_profile_register(get_cpu_device(policy->cpu),
cpudata->profile_name,
@@ -1427,7 +1425,7 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
if (ret)
epp = epp_values[ret];
else
- epp = amd_pstate_get_balanced_epp(policy);
+ epp = cpudata->epp_default_dc;
}
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
@@ -1707,6 +1705,8 @@ static int amd_pstate_change_driver_mode(int mode)
{
int ret;
+ lockdep_assert_held(&amd_pstate_driver_lock);
+
ret = amd_pstate_unregister_driver(0);
if (ret)
return ret;
@@ -1821,8 +1821,16 @@ static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
if (ret)
return ret;
- if (dynamic_epp == enabled)
+ guard(mutex)(&amd_pstate_driver_lock);
+
+ if (cppc_state != AMD_PSTATE_ACTIVE) {
+ pr_debug("dynamic_epp can only be toggled in active mode\n");
return -EINVAL;
+ }
+
+ /* Nothing to do */
+ if (dynamic_epp == enabled)
+ return count;
/* reinitialize with desired dynamic EPP value */
dynamic_epp = enabled;
@@ -1942,7 +1950,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
if (dynamic_epp)
ret = amd_pstate_set_dynamic_epp(policy);
else
- ret = amd_pstate_set_epp(policy, amd_pstate_get_balanced_epp(policy));
+ ret = amd_pstate_set_epp(policy, cpudata->epp_default_dc);
if (ret)
goto free_cpudata1;
@@ -1970,12 +1978,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
if (cpudata) {
union perf_cached perf = READ_ONCE(cpudata->perf);
+ if (cpudata->dynamic_epp)
+ amd_pstate_clear_dynamic_epp(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);
- if (cpudata->dynamic_epp)
- amd_pstate_clear_dynamic_epp(policy);
kfree(cpudata);
policy->driver_data = NULL;
}