Commit a67f3113 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge tag 'amd-pstate-v7.1-2026-05-14' of...

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
parents 85cffdb2 e4e9b7b3
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -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
===========================================
+0 −12
Original line number Diff line number Diff line
@@ -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
+29 −7
Original line number Diff line number Diff line
@@ -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;

+18 −9
Original line number Diff line number Diff line
@@ -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;
	}