mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
cpufreq/amd-pstate: Grab "amd_pstate_driver_lock" when toggling dynamic_epp
Concurrently changing driver mode and dynamic_epp with:
echo passive > /sys/devices/system/cpu/amd_pstate/status&
echo disable > /sys/devices/system/cpu/amd_pstate/dynamic_epp&
hits the WARN_ON_ONCE() in static_key_disable_cpuslocked() and hangs the
system since both sysfs writes are trying to do
amd_pstate_change_driver_mode() without any synchronization.
Grab the "amd_pstate_driver_lock" mutex when modifying "dynamic_epp" to
prevent the two paths from racing with each other. Add a lockdep
assertion for "amd_pstate_driver_lock" in
amd_pstate_change_driver_mode() to formalize the dependency.
Since "cppc_mode" is stable under "amd_pstate_driver_lock", only reload
the driver when in "AMD_PSTATE_ACTIVE" mode and reject all writes when
in passive or guided mode, or if the driver is not loaded, since only
active mode operates on EPP.
Fixes: e30ca6dd53 ("cpufreq/amd-pstate: Add dynamic energy performance preference")
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20260508051748.10484-2-kprateek.nayak@amd.com
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
This commit is contained in:
parent
7fd2df204f
commit
9228169d2a
|
|
@ -1707,6 +1707,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,6 +1823,13 @@ static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (dynamic_epp == enabled)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user