2023-12-04 07:29:50

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH] net: hns3: reduce stack usage in hclge_dbg_dump_tm_pri()

From: Arnd Bergmann <[email protected]>

This function exceeds the stack frame warning limit:

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c: In function 'hclge_dbg_dump_tm_pri':
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c:1039:1: error: the frame size of 1408 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

Use dynamic allocation for the largest stack object instead. It
would be nice to rewrite this file to completely avoid the extra
buffer and just use the one that was already allocated by debugfs,
but that is a much larger change.

Signed-off-by: Arnd Bergmann <[email protected]>
---
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
index ff3f8f424ad9..9b5d46fdfd6c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
@@ -981,7 +981,7 @@ static const struct hclge_dbg_item tm_pri_items[] = {

static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
{
- char data_str[ARRAY_SIZE(tm_pri_items)][HCLGE_DBG_DATA_STR_LEN];
+ char *data_str;
struct hclge_tm_shaper_para c_shaper_para, p_shaper_para;
char *result[ARRAY_SIZE(tm_pri_items)], *sch_mode_str;
char content[HCLGE_DBG_TM_INFO_LEN];
@@ -991,9 +991,13 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
ret = hclge_tm_get_pri_num(hdev, &pri_num);
if (ret)
return ret;
+ data_str = kcalloc(ARRAY_SIZE(tm_pri_items), HCLGE_DBG_DATA_STR_LEN,
+ GFP_KERNEL);
+ if (!data_str)
+ return -ENOMEM;

for (i = 0; i < ARRAY_SIZE(tm_pri_items); i++)
- result[i] = &data_str[i][0];
+ result[i] = &data_str[i * HCLGE_DBG_DATA_STR_LEN];

hclge_dbg_fill_content(content, sizeof(content), tm_pri_items,
NULL, ARRAY_SIZE(tm_pri_items));
@@ -1035,6 +1039,7 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
pos += scnprintf(buf + pos, len - pos, "%s", content);
}

+ kfree(data_str);
return 0;
}

--
2.39.2


2023-12-04 08:32:13

by Jijie Shao

[permalink] [raw]
Subject: Re: [PATCH] net: hns3: reduce stack usage in hclge_dbg_dump_tm_pri()


on 2023/12/4 15:29, Arnd Bergmann wrote:
> From: Arnd Bergmann <[email protected]>
>
>
> @@ -981,7 +981,7 @@ static const struct hclge_dbg_item tm_pri_items[] = {
>
> static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
> {
> - char data_str[ARRAY_SIZE(tm_pri_items)][HCLGE_DBG_DATA_STR_LEN];
> + char *data_str;
> struct hclge_tm_shaper_para c_shaper_para, p_shaper_para;
> char *result[ARRAY_SIZE(tm_pri_items)], *sch_mode_str;
> char content[HCLGE_DBG_TM_INFO_LEN];
> @@ -991,9 +991,13 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
> ret = hclge_tm_get_pri_num(hdev, &pri_num);
> if (ret)
> return ret;

Thanks,
But it would be better if there is an empty line here.

> + data_str = kcalloc(ARRAY_SIZE(tm_pri_items), HCLGE_DBG_DATA_STR_LEN,
> + GFP_KERNEL);
> + if (!data_str)
> + return -ENOMEM;
>
> for (i = 0; i < ARRAY_SIZE(tm_pri_items); i++)
> - result[i] = &data_str[i][0];
> + result[i] = &data_str[i * HCLGE_DBG_DATA_STR_LEN];
>
> hclge_dbg_fill_content(content, sizeof(content), tm_pri_items,
> NULL, ARRAY_SIZE(tm_pri_items));
> @@ -1035,6 +1039,7 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
> pos += scnprintf(buf + pos, len - pos, "%s", content);
> }
>

all exception condition also need to free memory before return. eg:
for (i = 0; i < pri_num; i++) {
ret = hclge_tm_get_pri_sch_mode(hdev, i, &sch_mode);
if (ret)
return ret;

ret = hclge_tm_get_pri_weight(hdev, i, &weight);
if (ret)
return ret;

> + kfree(data_str);
> return 0;
> }
>

2023-12-04 08:53:32

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] net: hns3: reduce stack usage in hclge_dbg_dump_tm_pri()

On Mon, Dec 4, 2023, at 09:31, Jijie Shao wrote:
> on 2023/12/4 15:29, Arnd Bergmann wrote:
>> From: Arnd Bergmann <[email protected]>
>>
>>
>> @@ -981,7 +981,7 @@ static const struct hclge_dbg_item tm_pri_items[] = {
>>
>> static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
>> {
>> - char data_str[ARRAY_SIZE(tm_pri_items)][HCLGE_DBG_DATA_STR_LEN];
>> + char *data_str;
>> struct hclge_tm_shaper_para c_shaper_para, p_shaper_para;
>> char *result[ARRAY_SIZE(tm_pri_items)], *sch_mode_str;
>> char content[HCLGE_DBG_TM_INFO_LEN];
>> @@ -991,9 +991,13 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len)
>> ret = hclge_tm_get_pri_num(hdev, &pri_num);
>> if (ret)
>> return ret;
>
> Thanks,
> But it would be better if there is an empty line here.

ok

>
> all exception condition also need to free memory before return. eg:


Indeed, I'll send a v2 in a bit.

Arnd