[PATCH] drm/amd/powerplay: honor hw limit on fetching metrics data for navi10

Quan, Evan Evan.Quan at amd.com
Fri Aug 2 04:17:41 UTC 2019


Reviewed-by: Evan Quan <evan.quan at amd.com>

> -----Original Message-----
> From: Wang, Kevin(Yang) <Kevin1.Wang at amd.com>
> Sent: Friday, August 02, 2019 12:14 PM
> To: dl.srdc_lnx_nv10 <dl.srdc_lnx_nv10 at amd.com>
> Cc: amd-gfx at lists.freedesktop.org; Quan, Evan <Evan.Quan at amd.com>;
> Feng, Kenneth <Kenneth.Feng at amd.com>; Wang, Kevin(Yang)
> <Kevin1.Wang at amd.com>
> Subject: [PATCH] drm/amd/powerplay: honor hw limit on fetching metrics
> data for navi10
> 
> too frequently to update mertrics table will cause smu internal error.
> 
> Signed-off-by: Kevin Wang <kevin1.wang at amd.com>
> ---
>  drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 56 +++++++++++++++-----
> --
>  1 file changed, 38 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> index f3adb713784a..cf2e264095a7 100644
> --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
> @@ -515,6 +515,8 @@ static int navi10_store_powerplay_table(struct
> smu_context *smu)
> 
>  static int navi10_tables_init(struct smu_context *smu, struct smu_table
> *tables)  {
> +	struct smu_table_context *smu_table = &smu->smu_table;
> +
>  	SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
>  		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
>  	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS,
> sizeof(Watermarks_t), @@ -529,9 +531,35 @@ static int
> navi10_tables_init(struct smu_context *smu, struct smu_table *tables)
>  		       sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
>  	               AMDGPU_GEM_DOMAIN_VRAM);
> 
> +	smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t),
> GFP_KERNEL);
> +	if (!smu_table->metrics_table)
> +		return -ENOMEM;
> +	smu_table->metrics_time = 0;
> +
>  	return 0;
>  }
> 
> +static int navi10_get_metrics_table(struct smu_context *smu,
> +				    SmuMetrics_t *metrics_table)
> +{
> +	struct smu_table_context *smu_table= &smu->smu_table;
> +	int ret = 0;
> +
> +	if (!smu_table->metrics_time || time_after(jiffies, smu_table-
> >metrics_time + HZ / 1000)) {
> +		ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS,
> 0,
> +				(void *)smu_table->metrics_table, false);
> +		if (ret) {
> +			pr_info("Failed to export SMU metrics table!\n");
> +			return ret;
> +		}
> +		smu_table->metrics_time = jiffies;
> +	}
> +
> +	memcpy(metrics_table, smu_table->metrics_table,
> sizeof(SmuMetrics_t));
> +
> +	return ret;
> +}
> +
>  static int navi10_allocate_dpm_context(struct smu_context *smu)  {
>  	struct smu_dpm_context *smu_dpm = &smu->smu_dpm; @@ -
> 611,15 +639,10 @@ static int navi10_get_current_clk_freq_by_table(struct
> smu_context *smu,
>  				       enum smu_clk_type clk_type,
>  				       uint32_t *value)
>  {
> -	static SmuMetrics_t metrics;
>  	int ret = 0, clk_id = 0;
> +	SmuMetrics_t metrics;
> 
> -	if (!value)
> -		return -EINVAL;
> -
> -	memset(&metrics, 0, sizeof(metrics));
> -
> -	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void
> *)&metrics, false);
> +	ret = navi10_get_metrics_table(smu, &metrics);
>  	if (ret)
>  		return ret;
> 
> @@ -907,8 +930,9 @@ static int navi10_get_gpu_power(struct smu_context
> *smu, uint32_t *value)
>  	if (!value)
>  		return -EINVAL;
> 
> -	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void
> *)&metrics,
> -			       false);
> +	ret = navi10_get_metrics_table(smu, &metrics);
> +	if (ret)
> +		return ret;
>  	if (ret)
>  		return ret;
> 
> @@ -927,10 +951,7 @@ static int navi10_get_current_activity_percent(struct
> smu_context *smu,
>  	if (!value)
>  		return -EINVAL;
> 
> -	msleep(1);
> -
> -	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
> -			       (void *)&metrics, false);
> +	ret = navi10_get_metrics_table(smu, &metrics);
>  	if (ret)
>  		return ret;
> 
> @@ -969,10 +990,9 @@ static int navi10_get_fan_speed_rpm(struct
> smu_context *smu,
>  	if (!speed)
>  		return -EINVAL;
> 
> -	memset(&metrics, 0, sizeof(metrics));
> -
> -	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
> -			       (void *)&metrics, false);
> +	ret = navi10_get_metrics_table(smu, &metrics);
> +	if (ret)
> +		return ret;
>  	if (ret)
>  		return ret;
> 
> @@ -1325,7 +1345,7 @@ static int navi10_thermal_get_temperature(struct
> smu_context *smu,
>  	if (!value)
>  		return -EINVAL;
> 
> -	ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void
> *)&metrics, false);
> +	ret = navi10_get_metrics_table(smu, &metrics);
>  	if (ret)
>  		return ret;
> 
> --
> 2.22.0



More information about the amd-gfx mailing list