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

drm/amd/powerplay: honor hw limit on fetching metrics data



Request too frequently may get corrupt data.

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 fe75a323
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -403,6 +403,9 @@ struct smu_context
	uint32_t default_power_profile_mode;

	uint32_t smc_if_version;

	unsigned long metrics_time;
	void *metrics_table;
};

struct pptable_funcs {
+31 −2
Original line number Diff line number Diff line
@@ -369,6 +369,13 @@ static int smu_v11_0_init_power(struct smu_context *smu)
		return -ENOMEM;
	smu_power->power_context_size = sizeof(struct smu_11_0_dpm_context);

	smu->metrics_time = 0;
	smu->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
	if (!smu->metrics_table) {
		kfree(smu_power->power_context);
		return -ENOMEM;
	}

	return 0;
}

@@ -379,7 +386,9 @@ static int smu_v11_0_fini_power(struct smu_context *smu)
	if (!smu_power->power_context || smu_power->power_context_size == 0)
		return -EINVAL;

	kfree(smu->metrics_table);
	kfree(smu_power->power_context);
	smu->metrics_table = NULL;
	smu_power->power_context = NULL;
	smu_power->power_context_size = 0;

@@ -1093,6 +1102,26 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
	return ret;
}

static int smu_v11_0_get_metrics_table(struct smu_context *smu,
		SmuMetrics_t *metrics_table)
{
	int ret = 0;

	if (!smu->metrics_time || time_after(jiffies, smu->metrics_time + HZ / 1000)) {
		ret = smu_update_table(smu, TABLE_SMU_METRICS,
				(void *)metrics_table, false);
		if (ret) {
			pr_info("Failed to export SMU metrics table!\n");
			return ret;
		}
		memcpy(smu->metrics_table, metrics_table, sizeof(SmuMetrics_t));
		smu->metrics_time = jiffies;
	} else
		memcpy(metrics_table, smu->metrics_table, sizeof(SmuMetrics_t));

	return ret;
}

static int smu_v11_0_get_current_activity_percent(struct smu_context *smu,
						  uint32_t *value)
{
@@ -1102,7 +1131,7 @@ static int smu_v11_0_get_current_activity_percent(struct smu_context *smu,
	if (!value)
		return -EINVAL;

	ret = smu_update_table(smu, TABLE_SMU_METRICS, (void *)&metrics, false);
	ret = smu_v11_0_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;

@@ -1139,7 +1168,7 @@ static int smu_v11_0_get_gpu_power(struct smu_context *smu, uint32_t *value)
	if (!value)
		return -EINVAL;

	ret = smu_update_table(smu, TABLE_SMU_METRICS, (void *)&metrics, false);
	ret = smu_v11_0_get_metrics_table(smu, &metrics);
	if (ret)
		return ret;