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

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
......@@ -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 {
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment