diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2025-03-12 09:44:19 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2025-03-19 15:52:56 -0400 |
commit | 553673a3e1bc0abbb994d9884f772189c739e3a0 (patch) | |
tree | 0a513eae9134f774886c49c0c513d2c010237d16 /drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | |
parent | fed7efbb43628f51e16e1890be8c84d136b755bf (diff) |
drm/amdgpu/gfx: fix ref counting for ring based profile handling
We need to make sure the workload profile ref counts are
balanced. This isn't currently the case because we can
increment the count on submissions, but the decrement may
be delayed as work comes in. Track when we enable the
workload profile so the references are balanced.
v2: switch to a mutex and active flag
v3: fix mutex init
Fixes: 8fdb3958e396 ("drm/amdgpu/gfx: add ring helpers for setting workload profile")
Cc: Yang Wang <kevinyang.wang@amd.com>
Cc: Kenneth Feng <kenneth.feng@amd.com>
Tested-by: Kenneth Feng <kenneth.feng@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 984e6ff6e463..099329d15b9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -2160,11 +2160,16 @@ void amdgpu_gfx_profile_idle_work_handler(struct work_struct *work) for (i = 0; i < (AMDGPU_MAX_COMPUTE_RINGS * AMDGPU_MAX_GC_INSTANCES); ++i) fences += amdgpu_fence_count_emitted(&adev->gfx.compute_ring[i]); if (!fences && !atomic_read(&adev->gfx.total_submission_cnt)) { - r = amdgpu_dpm_switch_power_profile(adev, profile, false); - if (r) - dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, - profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? - "fullscreen 3D" : "compute"); + mutex_lock(&adev->gfx.workload_profile_mutex); + if (adev->gfx.workload_profile_active) { + r = amdgpu_dpm_switch_power_profile(adev, profile, false); + if (r) + dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, + profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? + "fullscreen 3D" : "compute"); + adev->gfx.workload_profile_active = false; + } + mutex_unlock(&adev->gfx.workload_profile_mutex); } else { schedule_delayed_work(&adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT); } @@ -2184,11 +2189,16 @@ void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring) atomic_inc(&adev->gfx.total_submission_cnt); if (!cancel_delayed_work_sync(&adev->gfx.idle_work)) { - r = amdgpu_dpm_switch_power_profile(adev, profile, true); - if (r) - dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, - profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? - "fullscreen 3D" : "compute"); + mutex_lock(&adev->gfx.workload_profile_mutex); + if (!adev->gfx.workload_profile_active) { + r = amdgpu_dpm_switch_power_profile(adev, profile, true); + if (r) + dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, + profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? + "fullscreen 3D" : "compute"); + adev->gfx.workload_profile_active = true; + } + mutex_unlock(&adev->gfx.workload_profile_mutex); } } |