[PATCH 3/3] amdgpu/pm: Add Error Handling to emit_clocks stack

Quan, Evan Evan.Quan at amd.com
Mon Jan 24 03:01:08 UTC 2022


[AMD Official Use Only]

It seems this patch should be combined with patch1. Rather than as a separate patch.

BR
Evan
> -----Original Message-----
> From: Powell, Darren <Darren.Powell at amd.com>
> Sent: Saturday, January 22, 2022 11:47 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Powell, Darren <Darren.Powell at amd.com>
> Subject: [PATCH 3/3] amdgpu/pm: Add Error Handling to emit_clocks stack
> 
>  Previous implementation of print_clocks required return of bytes written
>  to calling function via return value. Passing this value in by reference
>  allows us now to pass back error codes up the calling stack.
> 
>  (v1)
>  - Errors from get_current_clk_freq, get_dpm_level_count & get_dpm_freq
>       now passed back up the stack
>  - Added -EOPNOTSUPP when encountering for OD clocks
>       !od_enabled
>       missing od_table or od_settings
>  - OD_RANGE continues to print any subset of the ODCAP settings it can find
>       without reporting error for any missing
>  - smu_emit_ppclk returns ENOENT if emit_clk_levels is not supported by the
>       device
>  - modified calling logic so fallback to print_clock_levels is only attempted
>       if emit_clk_levels is not (yet) supported by the device
> 
>  (v2)
>  - change return from amdgpu_dpm_emit_clock_levels if emit_clock_levels
> not found
>  - updated documentation of pptable_func members print_clk_levels,
> emit_clk_levels
> 
>  == Test ==
>  LOGFILE=pp_clk.test.log
>  AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`
>  AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |
> awk '{print $9}'`
>  HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}
> 
>  lspci -nn | grep "VGA\|Display"  > $LOGFILE
>  FILES="pp_od_clk_voltage
>  pp_dpm_sclk
>  pp_dpm_mclk
>  pp_dpm_pcie
>  pp_dpm_socclk
>  pp_dpm_fclk
>  pp_dpm_dcefclk
>  pp_dpm_vclk
>  pp_dpm_dclk "
> 
>  for f in $FILES
>  do
>    echo === $f === >> $LOGFILE
>    cat $HWMON_DIR/device/$f >> $LOGFILE
>  done
>  cat $LOGFILE
> 
> Signed-off-by: Darren Powell <darren.powell at amd.com>
> ---
>  drivers/gpu/drm/amd/pm/amdgpu_dpm.c           |  2 +-
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c            | 13 ++++++------
>  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     |  8 +++----
>  drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  6 +++++-
>  .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   | 21 +++++++++---------
> -
>  5 files changed, 25 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> index e45578124928..03a690a3abb7 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> @@ -915,7 +915,7 @@ int amdgpu_dpm_emit_clock_levels(struct
> amdgpu_device *adev,
>  	int ret = 0;
> 
>  	if (!pp_funcs->emit_clock_levels)
> -		return 0;
> +		return -ENOENT;
> 
>  	mutex_lock(&adev->pm.mutex);
>  	ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 97a8dcbe6eaf..a11def0ee761 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -855,13 +855,12 @@ static ssize_t
> amdgpu_get_pp_od_clk_voltage(struct device *dev,
>  		return ret;
>  	}
> 
> -	ret = amdgpu_dpm_emit_clock_levels(adev, od_clocks[0], buf,
> &size);
> -	if (ret >= 0) {
> -		/* Proceed with emit for other od clocks if the first call
> succeeds */
> -		for(clk_index = 1 ; clk_index < 6 ; clk_index++)
> -			amdgpu_dpm_emit_clock_levels(adev,
> od_clocks[clk_index], buf, &size);
> +	for(clk_index = 0 ; clk_index < 6 ; clk_index++) {
> +		ret = amdgpu_dpm_emit_clock_levels(adev,
> od_clocks[clk_index], buf, &size);
> +		if (ret)
> +			break;
>  	}
> -	else {
> +	if (ret == -ENOENT) {
>  		size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
>  		if (size > 0) {
>  			size += amdgpu_dpm_print_clock_levels(adev,
> OD_MCLK, buf+size);
> @@ -1014,7 +1013,7 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct
> device *dev,
>  	}
> 
>  	ret = amdgpu_dpm_emit_clock_levels(adev, type, buf, &size);
> -	if (ret < 0)
> +	if (ret == -ENOENT)
>  		size = amdgpu_dpm_print_clock_levels(adev, type, buf);
> 
>  	if (size == 0)
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index d82ea7ee223f..29c101a93dc4 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -2454,12 +2454,10 @@ static int smu_emit_ppclk_levels(void *handle,
> enum pp_clock_type type, char *bu
>  	if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
>  		return -EOPNOTSUPP;
> 
> -	if (smu->ppt_funcs->emit_clk_levels) {
> +	if (smu->ppt_funcs->emit_clk_levels)
>  		ret = smu->ppt_funcs->emit_clk_levels(smu, clk_type, buf,
> offset);
> -	}
> -	else {
> -		ret = -EOPNOTSUPP;
> -	}
> +	else
> +		ret = -ENOENT;
> 
>  	return ret;
> 
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> index 224b869eda70..1429581dca9c 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> @@ -612,6 +612,7 @@ struct pptable_funcs {
>  	 *                    to buffer. Star current level.
>  	 *
>  	 * Used for sysfs interfaces.
> +	 * Return: Number of characters written to the buffer
>  	 */
>  	int (*print_clk_levels)(struct smu_context *smu, enum
> smu_clk_type clk_type, char *buf);
> 
> @@ -621,7 +622,10 @@ struct pptable_funcs {
>  	 *
>  	 * Used for sysfs interfaces.
>  	 * &buf: sysfs buffer
> -	 * &offset: offset within buffer to start printing
> +	 * &offset: offset within buffer to start printing, which is updated by
> the
> +	 * function.
> +	 *
> +	 * Return: 0 on Success or Negative to indicate an error occurred.
>  	 */
>  	int (*emit_clk_levels)(struct smu_context *smu, enum
> smu_clk_type clk_type, char *buf, int *offset);
> 
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> index 50022de5337f..4bcef7d1a0d6 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> @@ -1278,7 +1278,6 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		(OverDriveTable_t *)table_context->overdrive_table;
>  	struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
>  	uint32_t min_value, max_value;
> -	int save_offset = *offset;
> 
>  	switch (clk_type) {
>  	case SMU_GFXCLK:
> @@ -1292,17 +1291,17 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  	case SMU_DCEFCLK:
>  		ret = navi10_get_current_clk_freq_by_table(smu, clk_type,
> &cur_value);
>  		if (ret)
> -			return 0;
> +			return ret;
> 
>  		ret = smu_v11_0_get_dpm_level_count(smu, clk_type,
> &count);
>  		if (ret)
> -			return 0;
> +			return ret;
> 
>  		if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {
>  			for (i = 0; i < count; i++) {
>  				ret =
> smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
>  				if (ret)
> -					return (*offset - save_offset);
> +					return ret;
> 
>  				*offset += sysfs_emit_at(buf, *offset,
> "%d: %uMhz %s\n", i, value,
>  						cur_value == value ? "*" : "");
> @@ -1311,10 +1310,10 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		} else {
>  			ret = smu_v11_0_get_dpm_freq_by_index(smu,
> clk_type, 0, &freq_values[0]);
>  			if (ret)
> -				return 0;
> +				return ret;
>  			ret = smu_v11_0_get_dpm_freq_by_index(smu,
> clk_type, count - 1, &freq_values[2]);
>  			if (ret)
> -				return 0;
> +				return ret;
> 
>  			freq_values[1] = cur_value;
>  			mark_index = cur_value == freq_values[0] ? 0 :
> @@ -1355,7 +1354,7 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		break;
>  	case SMU_OD_SCLK:
>  		if (!smu->od_enabled || !od_table || !od_settings)
> -			break;
> +			return -EOPNOTSUPP;
>  		if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODCAP_GFXCLK_LIMITS))
>  			break;
>  		*offset += sysfs_emit_at(buf, *offset,
> "OD_SCLK:\n0: %uMhz\n1: %uMhz\n",
> @@ -1363,14 +1362,14 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		break;
>  	case SMU_OD_MCLK:
>  		if (!smu->od_enabled || !od_table || !od_settings)
> -			break;
> +			return -EOPNOTSUPP;
>  		if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODCAP_UCLK_MAX))
>  			break;
>  		*offset += sysfs_emit_at(buf, *offset,
> "OD_MCLK:\n1: %uMHz\n", od_table->UclkFmax);
>  		break;
>  	case SMU_OD_VDDC_CURVE:
>  		if (!smu->od_enabled || !od_table || !od_settings)
> -			break;
> +			return -EOPNOTSUPP;
>  		if (!navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODCAP_GFXCLK_CURVE))
>  			break;
>  		*offset += sysfs_emit_at(buf, *offset,
> "OD_VDDC_CURVE:\n");
> @@ -1395,7 +1394,7 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		break;
>  	case SMU_OD_RANGE:
>  		if (!smu->od_enabled || !od_table || !od_settings)
> -			break;
> +			return -EOPNOTSUPP;
>  		*offset += sysfs_emit_at(buf, *offset, "%s:\n",
> "OD_RANGE");
> 
>  		if (navi10_od_feature_is_supported(od_settings,
> SMU_11_0_ODCAP_GFXCLK_LIMITS)) {
> @@ -1446,7 +1445,7 @@ static int navi10_emit_clk_levels(struct
> smu_context *smu,
>  		break;
>  	}
> 
> -	return (*offset - save_offset);
> +	return 0;
>  }
> 
>  static int navi10_print_clk_levels(struct smu_context *smu,
> --
> 2.34.1


More information about the amd-gfx mailing list