Commit cf3fde89 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/powerplay: fix deadlock on setting power_dpm_force_performance_level



smu_enable_umd_pstate() will try to get the smu->mutex which was already
hold by its parent API smu_force_performance_level() on the call path.
Thus deadlock happens.

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarFeifei Xu <Feifei.Xu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 60599a03
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -383,14 +383,25 @@ bool smu_clk_dpm_is_enabled(struct smu_context *smu, enum smu_clk_type clk_type)
	return true;
}


/**
 * smu_dpm_set_power_gate - power gate/ungate the specific IP block
 *
 * @smu:        smu_context pointer
 * @block_type: the IP block to power gate/ungate
 * @gate:       to power gate if true, ungate otherwise
 *
 * This API uses no smu->mutex lock protection due to:
 * 1. It is either called by other IP block(gfx/sdma/vcn/uvd/vce).
 *    This is guarded to be race condition free by the caller.
 * 2. Or get called on user setting request of power_dpm_force_performance_level.
 *    Under this case, the smu->mutex lock protection is already enforced on
 *    the parent API smu_force_performance_level of the call path.
 */
int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
			   bool gate)
{
	int ret = 0;

	mutex_lock(&smu->mutex);

	switch (block_type) {
	case AMD_IP_BLOCK_TYPE_UVD:
		ret = smu_dpm_set_uvd_enable(smu, gate);
@@ -408,8 +419,6 @@ int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
		break;
	}

	mutex_unlock(&smu->mutex);

	return ret;
}