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

Reply via email to