mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-30 11:17:42 +08:00
drm/amd/pm: fix race in power state check before mutex lock
The power state check in amdgpu_dpm_set_powergating_by_smu() is done before acquiring the pm mutex, leading to a race condition where: 1. Thread A checks state and thinks no change is needed 2. Thread B acquires mutex and modifies the state 3. Thread A returns without updating state, causing inconsistency Fix this by moving the mutex lock before the power state check, ensuring atomicity of the state check and modification. Fixes:6ee27ee27b("drm/amd/pm: avoid duplicate powergate/ungate setting") Signed-off-by: Yang Wang <kevinyang.wang@amd.com> Reviewed-by: Kenneth Feng <kenneth.feng@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit7a3fbdfd19)
This commit is contained in:
@@ -80,15 +80,15 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev,
|
||||
enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
|
||||
bool is_vcn = block_type == AMD_IP_BLOCK_TYPE_VCN;
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
|
||||
if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state &&
|
||||
(!is_vcn || adev->vcn.num_vcn_inst == 1)) {
|
||||
dev_dbg(adev->dev, "IP block%d already in the target %s state!",
|
||||
block_type, gate ? "gate" : "ungate");
|
||||
return 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
|
||||
switch (block_type) {
|
||||
case AMD_IP_BLOCK_TYPE_UVD:
|
||||
case AMD_IP_BLOCK_TYPE_VCE:
|
||||
@@ -115,6 +115,7 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev,
|
||||
if (!ret)
|
||||
atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user