Commit 553673a3 authored by Alex Deucher's avatar Alex Deucher
Browse files

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: 8fdb3958 ("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: default avatarKenneth Feng <kenneth.feng@amd.com>
Reviewed-by: default avatarKenneth Feng <kenneth.feng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fed7efbb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);

+20 −10
Original line number Diff line number Diff line
@@ -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)) {
		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)) {
		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);
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -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 {