[AMD Official Use Only - AMD Internal Distribution Only]

Reviewed-by: Kenneth Feng <[email protected]>


-----Original Message-----
From: Wang, Yang(Kevin) <[email protected]>
Sent: Tuesday, January 27, 2026 11:11 AM
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander 
<[email protected]>; Feng, Kenneth <[email protected]>
Subject: [PATCH] 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: 6ee27ee27ba8 ("drm/amd/pm: avoid duplicate powergate/ungate setting")

Signed-off-by: Yang Wang <[email protected]>
---
 drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 4214f7314963..feadf604b474 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -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;
--
2.34.1

Reply via email to