]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amdgpu/gfx: fix ref counting for ring based profile handling
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 12 Mar 2025 13:44:19 +0000 (09:44 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 19 Mar 2025 19:52:56 +0000 (15:52 -0400)
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>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h

index 35ace1368b9ca7f30160c982023d3d6c68be5eb8..173048c46fc3efcae66d788ef949c1179d53a008 100644 (file)
@@ -4282,6 +4282,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        /* Initialize the mutex for cleaner shader isolation between GFX and compute processes */
        mutex_init(&adev->enforce_isolation_mutex);
        mutex_init(&adev->gfx.kfd_sch_mutex);
+       mutex_init(&adev->gfx.workload_profile_mutex);
 
        amdgpu_device_init_apu_flags(adev);
 
index 984e6ff6e4632a02ca01a616171efdcd93c1b7d1..099329d15b9ffd0318fd49faf590d90316d04bdf 100644 (file)
@@ -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);
        }
 }
 
index 3c030d3f39d459a1562753c28167f48ab6a149b6..9e2355a3b12059c788449337c3fb206357eb9a50 100644 (file)
@@ -482,6 +482,8 @@ struct amdgpu_gfx {
 
        atomic_t                        total_submission_cnt;
        struct delayed_work             idle_work;
+       bool                            workload_profile_active;
+       struct mutex                    workload_profile_mutex;
 };
 
 struct amdgpu_gfx_ras_reg_entry {