mirror of https://github.com/torvalds/linux.git
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>
This commit is contained in:
parent
37e6349e93
commit
7a3fbdfd19
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue