Check sysfs_emit_at() in emit_clk_levels() for smu_v13_0_4, smu_v13_0_5, yellow_carp, aldebaran, and smu_v13_0_6 (OD sysfs and OD_FCLK on v13_0_6) and stop emitting when the sysfs page is full
Signed-off-by: Asad Kamal <[email protected]> --- .../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 36 +++++++--- .../drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c | 68 +++++++++++++------ .../drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c | 66 +++++++++++++----- .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 45 ++++++++---- .../drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 66 +++++++++++++----- 5 files changed, 203 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 3a19f0ffcf3c..2d4c557c04e9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -791,7 +791,7 @@ static int aldebaran_get_current_clk_freq_by_table(struct smu_context *smu, static int aldebaran_emit_clk_levels(struct smu_context *smu, enum smu_clk_type type, char *buf, int *offset) { - int ret = 0; + int ret = 0, n; struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; struct smu_dpm_table *single_dpm_table = NULL; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; @@ -800,7 +800,10 @@ static int aldebaran_emit_clk_levels(struct smu_context *smu, static const char attempt_string[] = "Attempt to get current"; if (amdgpu_ras_intr_triggered()) { - *offset += sysfs_emit_at(buf, *offset, "unavailable\n"); + int unr = sysfs_emit_at(buf, *offset, "unavailable\n"); + + if (unr) + *offset += unr; return -EBUSY; } @@ -808,16 +811,28 @@ static int aldebaran_emit_clk_levels(struct smu_context *smu, switch (type) { case SMU_OD_SCLK: - *offset += sysfs_emit_at(buf, *offset, "%s:\n", "OD_SCLK"); - *offset += sysfs_emit_at(buf, *offset, "0: %uMhz\n1: %uMhz\n", - pstate_table->gfxclk_pstate.curr.min, - pstate_table->gfxclk_pstate.curr.max); + n = sysfs_emit_at(buf, *offset, "%s:\n", "OD_SCLK"); + if (!n) + goto out; + *offset += n; + n = sysfs_emit_at(buf, *offset, "0: %uMhz\n1: %uMhz\n", + pstate_table->gfxclk_pstate.curr.min, + pstate_table->gfxclk_pstate.curr.max); + if (!n) + goto out; + *offset += n; return 0; case SMU_OD_MCLK: - *offset += sysfs_emit_at(buf, *offset, "%s:\n", "OD_MCLK"); - *offset += sysfs_emit_at(buf, *offset, "0: %uMhz\n1: %uMhz\n", - pstate_table->uclk_pstate.curr.min, - pstate_table->uclk_pstate.curr.max); + n = sysfs_emit_at(buf, *offset, "%s:\n", "OD_MCLK"); + if (!n) + goto out; + *offset += n; + n = sysfs_emit_at(buf, *offset, "0: %uMhz\n1: %uMhz\n", + pstate_table->uclk_pstate.curr.min, + pstate_table->uclk_pstate.curr.max); + if (!n) + goto out; + *offset += n; return 0; case SMU_SCLK: @@ -842,6 +857,7 @@ static int aldebaran_emit_clk_levels(struct smu_context *smu, return -EINVAL; } +out: if (single_dpm_table) { ret = aldebaran_get_current_clk_freq_by_table(smu, type, &cur_value); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index 167b3499f7f1..903d81a74ede 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -503,23 +503,40 @@ static int smu_v13_0_4_emit_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf, int *offset) { - int i, idx, size = *offset, ret = 0, start_offset = *offset; + int i, idx, size = *offset, ret = 0, start_offset = *offset, n; uint32_t cur_value = 0, value = 0, count = 0; uint32_t min, max; switch (clk_type) { case SMU_OD_SCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); - size += sysfs_emit_at(buf, size, "0: %10uMhz\n", - (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); - size += sysfs_emit_at(buf, size, "1: %10uMhz\n", - (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %10uMhz\n", + (smu->gfx_actual_hard_min_freq > 0) ? + smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %10uMhz\n", + (smu->gfx_actual_soft_max_freq > 0) ? + smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_OD_RANGE: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); - size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", - smu->gfx_default_hard_min_freq, - smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", + smu->gfx_default_hard_min_freq, + smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_SOCCLK: case SMU_VCLK: @@ -540,8 +557,11 @@ static int smu_v13_0_4_emit_clk_levels(struct smu_context *smu, if (ret) return ret; - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, - cur_value == value ? "*" : ""); + n = sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, + cur_value == value ? "*" : ""); + if (!n) + goto out; + size += n; } break; case SMU_GFXCLK: @@ -557,18 +577,28 @@ static int smu_v13_0_4_emit_clk_levels(struct smu_context *smu, i = 0; else i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, - i == 2 ? "*" : ""); + n = sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, + i == 0 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %uMhz %s\n", + i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ + i == 1 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, + i == 2 ? "*" : ""); + if (!n) + goto out; + size += n; break; default: break; } +out: *offset += size - start_offset; return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index 141e778333c5..d26beb4cd6d7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -868,22 +868,39 @@ static int smu_v13_0_5_emit_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf, int *offset) { - int i, idx, size = *offset, ret = 0, start_offset = *offset; + int i, idx, size = *offset, ret = 0, start_offset = *offset, n; uint32_t cur_value = 0, value = 0, count = 0; uint32_t min = 0, max = 0; switch (clk_type) { case SMU_OD_SCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); - size += sysfs_emit_at(buf, size, "0: %10uMhz\n", - (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); - size += sysfs_emit_at(buf, size, "1: %10uMhz\n", - (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %10uMhz\n", + (smu->gfx_actual_hard_min_freq > 0) ? + smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %10uMhz\n", + (smu->gfx_actual_soft_max_freq > 0) ? + smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_OD_RANGE: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); - size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", - smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", + smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_SOCCLK: case SMU_VCLK: @@ -903,8 +920,11 @@ static int smu_v13_0_5_emit_clk_levels(struct smu_context *smu, if (ret) return ret; - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, - cur_value == value ? "*" : ""); + n = sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, + cur_value == value ? "*" : ""); + if (!n) + goto out; + size += n; } break; case SMU_GFXCLK: @@ -920,18 +940,28 @@ static int smu_v13_0_5_emit_clk_levels(struct smu_context *smu, i = 0; else i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : SMU_13_0_5_UMD_PSTATE_GFXCLK, - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, - i == 2 ? "*" : ""); + n = sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, + i == 0 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %uMhz %s\n", + i == 1 ? cur_value : SMU_13_0_5_UMD_PSTATE_GFXCLK, + i == 1 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, + i == 2 ? "*" : ""); + if (!n) + goto out; + size += n; break; default: break; } +out: *offset += size - start_offset; return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index ce520f43ab94..3d2bcdab1621 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -1387,7 +1387,7 @@ static int smu_v13_0_6_emit_clk_levels(struct smu_context *smu, enum smu_clk_type type, char *buf, int *offset) { - int now, size = *offset, start_offset = *offset; + int now, size = *offset, start_offset = *offset, n; int ret = 0; struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; struct smu_dpm_table *single_dpm_table = NULL; @@ -1403,28 +1403,46 @@ static int smu_v13_0_6_emit_clk_levels(struct smu_context *smu, switch (type) { case SMU_OD_SCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); - size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", - pstate_table->gfxclk_pstate.curr.min, - pstate_table->gfxclk_pstate.curr.max); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", + pstate_table->gfxclk_pstate.curr.min, + pstate_table->gfxclk_pstate.curr.max); + if (!n) + goto out; + size += n; break; case SMU_OD_MCLK: if (!smu_v13_0_6_cap_supported(smu, SMU_CAP(SET_UCLK_MAX))) return -EOPNOTSUPP; - size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); - size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", - pstate_table->uclk_pstate.curr.min, - pstate_table->uclk_pstate.curr.max); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", + pstate_table->uclk_pstate.curr.min, + pstate_table->uclk_pstate.curr.max); + if (!n) + goto out; + size += n; break; case SMU_OD_FCLK: if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) return -EOPNOTSUPP; - size += sysfs_emit_at(buf, size, "%s:\n", "OD_FCLK"); - size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", - pstate_table->fclk_pstate.curr.min, - pstate_table->fclk_pstate.curr.max); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_FCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", + pstate_table->fclk_pstate.curr.min, + pstate_table->fclk_pstate.curr.max); + if (!n) + goto out; + size += n; break; case SMU_SCLK: case SMU_GFXCLK: @@ -1462,6 +1480,7 @@ static int smu_v13_0_6_emit_clk_levels(struct smu_context *smu, buf, offset); } +out: *offset += size - start_offset; return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index 748b5b074fff..e668af4df402 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -1048,23 +1048,40 @@ static int yellow_carp_emit_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf, int *offset) { - int i, idx, size = *offset, ret = 0, start_offset = *offset; + int i, idx, size = *offset, ret = 0, start_offset = *offset, n; uint32_t cur_value = 0, value = 0, count = 0; uint32_t min, max; uint32_t clk_limit = 0; switch (clk_type) { case SMU_OD_SCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); - size += sysfs_emit_at(buf, size, "0: %10uMhz\n", - (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); - size += sysfs_emit_at(buf, size, "1: %10uMhz\n", - (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "0: %10uMhz\n", + (smu->gfx_actual_hard_min_freq > 0) ? + smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %10uMhz\n", + (smu->gfx_actual_soft_max_freq > 0) ? + smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_OD_RANGE: - size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); - size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", - smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); + n = sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", + smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); + if (!n) + goto out; + size += n; break; case SMU_SOCCLK: case SMU_VCLK: @@ -1085,8 +1102,11 @@ static int yellow_carp_emit_clk_levels(struct smu_context *smu, if (ret) return ret; - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, - cur_value == value ? "*" : ""); + n = sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, + cur_value == value ? "*" : ""); + if (!n) + goto out; + size += n; } break; case SMU_GFXCLK: @@ -1103,18 +1123,28 @@ static int yellow_carp_emit_clk_levels(struct smu_context *smu, i = 0; else i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : clk_limit, - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, - i == 2 ? "*" : ""); + n = sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, + i == 0 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "1: %uMhz %s\n", + i == 1 ? cur_value : clk_limit, + i == 1 ? "*" : ""); + if (!n) + goto out; + size += n; + n = sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, + i == 2 ? "*" : ""); + if (!n) + goto out; + size += n; break; default: break; } +out: *offset += size - start_offset; return 0; -- 2.46.0
