From 6b93c86600fd64a05acb7336a96d368090f89cef Mon Sep 17 00:00:00 2001 From: huangdonghua Date: Fri, 11 Jul 2025 10:56:36 +0800 Subject: [PATCH 1/6] Revert "net: hns3: initialize reset_timer before hclgevf_misc_irq_init()" driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 ---------------------------------------------------------------------- This reverts commit 9e4dbb8ada72a05c2a7547b351b41ceec287be07. Signed-off-by: Donghua Huang --- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index e49eef9aa3fe..b41fc70e147c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2398,7 +2398,6 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); - timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); mutex_init(&hdev->mbx_resp.mbx_mutex); sema_init(&hdev->reset_sem, 1); @@ -3103,6 +3102,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) HCLGEVF_DRIVER_NAME); hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); return 0; -- Gitee From de20159971b8cb42346177fde1626457134eb63a Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Fri, 11 Jul 2025 10:56:37 +0800 Subject: [PATCH 2/6] net: hns3: initialize reset_timer before hclgevf_misc_irq_init() mainline inclusion from mainline-v6.13-rc7 commit 247fd1e33e1cd156aabe444e932d2648d33f1245 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=247fd1e33e1cd156aabe444e932d2648d33f1245 ---------------------------------------------------------------------- Currently the misc irq is initialized before reset_timer setup. But it will access the reset_timer in the irq handler. So initialize the reset_timer earlier. Fixes: ff200099d271 ("net: hns3: remove unnecessary work in hclgevf_main") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao Link: https://patch.msgid.link/20250106143642.539698-6-shaojijie@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Donghua Huang --- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index b41fc70e147c..68c59a3f38d9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2398,6 +2398,8 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); + /* timer needs to be initialized before misc irq */ + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); mutex_init(&hdev->mbx_resp.mbx_mutex); sema_init(&hdev->reset_sem, 1); @@ -3102,7 +3104,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) HCLGEVF_DRIVER_NAME); hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); - timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); + return 0; -- Gitee From b6dd24630ca9a0cb2158b9e6c86733ba71db292d Mon Sep 17 00:00:00 2001 From: huangdonghua Date: Fri, 11 Jul 2025 10:56:38 +0800 Subject: [PATCH 3/6] Revert "net: hns3: Resolved the issue that the debugfs query result is inconsistent." driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 ---------------------------------------------------------------------- This reverts commit 233f4df4386484caa52a3ed036f8e983795e0c0c. Signed-off-by: Donghua Huang --- drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index c9e645e88454..790728d751f7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -1295,10 +1295,8 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, /* save the buffer addr until the last read operation */ *save_buf = read_buf; - } - /* get data ready for the first time to read */ - if (!*ppos) { + /* get data ready for the first time to read */ ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, read_buf, hns3_dbg_cmd[index].buf_len); if (ret) -- Gitee From b2827d06ec66dddd880408afea19cf980796a508 Mon Sep 17 00:00:00 2001 From: Hao Lan Date: Fri, 11 Jul 2025 10:56:39 +0800 Subject: [PATCH 4/6] net: hns3: Resolved the issue that the debugfs query result is inconsistent. mainline inclusion from mainline-v6.13-rc7 commit 5191a8d3c2ab5bc01930ea3425e06a739af5b0e9 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=5191a8d3c2ab5bc01930ea3425e06a739af5b0e9 ---------------------------------------------------------------------- This patch modifies the implementation of debugfs: When the user process stops unexpectedly, not all data of the file system is read. In this case, the save_buf pointer is not released. When the user process is called next time, save_buf is used to copy the cached data to the user space. As a result, the queried data is stale. To solve this problem, this patch implements .open() and .release() handler for debugfs file_operations. moving allocation buffer and execution of the cmd to the .open() handler and freeing in to the .release() handler. Allocate separate buffer for each reader and associate the buffer with the file pointer. When different user read processes no longer share the buffer, the stale data problem is fixed. Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process") Signed-off-by: Hao Lan Signed-off-by: Guangwei Zhang Signed-off-by: Jijie Shao Reviewed-by: Michal Swiatkowski Link: https://patch.msgid.link/20250106143642.539698-4-shaojijie@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Donghua Huang --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 - .../ethernet/hisilicon/hns3/hns3_debugfs.c | 96 ++++++------------- 2 files changed, 31 insertions(+), 68 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 1082dd06a7db..5a702b014752 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -967,9 +967,6 @@ struct hnae3_handle { u8 netdev_flags; struct dentry *hnae3_dbgfs; - /* protects concurrent contention between debugfs commands */ - struct mutex dbgfs_lock; - char **dbgfs_buf; /* Network interface message level enabled bits */ u32 msg_enable; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 790728d751f7..0cc52cbe80bd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -1262,69 +1262,55 @@ static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { - struct hns3_dbg_data *dbg_data = filp->private_data; + char *buf = filp->private_data; + + return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); +} + +static int hns3_dbg_open(struct inode *inode, struct file *filp) +{ + struct hns3_dbg_data *dbg_data = inode->i_private; struct hnae3_handle *handle = dbg_data->handle; struct hns3_nic_priv *priv = handle->priv; - ssize_t size = 0; - char **save_buf; - char *read_buf; u32 index; + char *buf; int ret; + if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || + test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) + return -EBUSY; + ret = hns3_dbg_get_cmd_index(dbg_data, &index); if (ret) return ret; - mutex_lock(&handle->dbgfs_lock); - save_buf = &handle->dbgfs_buf[index]; - - if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || - test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { - ret = -EBUSY; - goto out; - } - - if (*save_buf) { - read_buf = *save_buf; - } else { - read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); - if (!read_buf) { - ret = -ENOMEM; - goto out; - } - - /* save the buffer addr until the last read operation */ - *save_buf = read_buf; - - /* get data ready for the first time to read */ - ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, - read_buf, hns3_dbg_cmd[index].buf_len); - if (ret) - goto out; - } + buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; - size = simple_read_from_buffer(buffer, count, ppos, read_buf, - strlen(read_buf)); - if (size > 0) { - mutex_unlock(&handle->dbgfs_lock); - return size; + ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, + buf, hns3_dbg_cmd[index].buf_len); + if (ret) { + kvfree(buf); + return ret; } -out: - /* free the buffer for the last read operation */ - if (*save_buf) { - kvfree(*save_buf); - *save_buf = NULL; - } + filp->private_data = buf; + return 0; +} - mutex_unlock(&handle->dbgfs_lock); - return ret; +static int hns3_dbg_release(struct inode *inode, struct file *filp) +{ + kvfree(filp->private_data); + filp->private_data = NULL; + return 0; } static const struct file_operations hns3_dbg_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = hns3_dbg_open, .read = hns3_dbg_read, + .release = hns3_dbg_release, }; static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) @@ -1381,13 +1367,6 @@ int hns3_dbg_init(struct hnae3_handle *handle) int ret; u32 i; - handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev, - ARRAY_SIZE(hns3_dbg_cmd), - sizeof(*handle->dbgfs_buf), - GFP_KERNEL); - if (!handle->dbgfs_buf) - return -ENOMEM; - hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = debugfs_create_dir(name, hns3_dbgfs_root); handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; @@ -1397,8 +1376,6 @@ int hns3_dbg_init(struct hnae3_handle *handle) debugfs_create_dir(hns3_dbg_dentry[i].name, handle->hnae3_dbgfs); - mutex_init(&handle->dbgfs_lock); - for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) || @@ -1427,24 +1404,13 @@ int hns3_dbg_init(struct hnae3_handle *handle) out: debugfs_remove_recursive(handle->hnae3_dbgfs); handle->hnae3_dbgfs = NULL; - mutex_destroy(&handle->dbgfs_lock); return ret; } void hns3_dbg_uninit(struct hnae3_handle *handle) { - u32 i; - debugfs_remove_recursive(handle->hnae3_dbgfs); handle->hnae3_dbgfs = NULL; - - for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) - if (handle->dbgfs_buf[i]) { - kvfree(handle->dbgfs_buf[i]); - handle->dbgfs_buf[i] = NULL; - } - - mutex_destroy(&handle->dbgfs_lock); } void hns3_dbg_register_debugfs(const char *debugfs_dir_name) -- Gitee From b01c2cc523db428eff50a902607649e1a3472593 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 11 Jul 2025 10:56:40 +0800 Subject: [PATCH 5/6] net: hns3: reduce stack usage in hclge_dbg_dump_tm_pri() mainline inclusion from mainline-v6.13-rc7 commit 2ff46b9eca2bb86c364942e86fd0145d56b62e40 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=2ff46b9eca2bb86c364942e86fd0145d56b62e40 ---------------------------------------------------------------------- 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 Link: https://lore.kernel.org/r/20231204085735.4112882-1-arnd@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Donghua Huang --- .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index dc00fc511365..4a5c9fff17c6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -1635,19 +1635,24 @@ 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]; 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]; u8 pri_num, sch_mode, weight, i, j; + char *data_str; int pos, ret; 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)); @@ -1656,23 +1661,23 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len) for (i = 0; i < pri_num; i++) { ret = hclge_tm_get_pri_sch_mode(hdev, i, &sch_mode); if (ret) - return ret; + goto out; ret = hclge_tm_get_pri_weight(hdev, i, &weight); if (ret) - return ret; + goto out; ret = hclge_tm_get_pri_shaper(hdev, i, HCLGE_OPC_TM_PRI_C_SHAPPING, &c_shaper_para); if (ret) - return ret; + goto out; ret = hclge_tm_get_pri_shaper(hdev, i, HCLGE_OPC_TM_PRI_P_SHAPPING, &p_shaper_para); if (ret) - return ret; + goto out; sch_mode_str = sch_mode & HCLGE_TM_TX_SCHD_DWRR_MSK ? "dwrr" : "sp"; @@ -1689,7 +1694,9 @@ static int hclge_dbg_dump_tm_pri(struct hclge_dev *hdev, char *buf, int len) pos += scnprintf(buf + pos, len - pos, "%s", content); } - return 0; +out: + kfree(data_str); + return ret; } static const struct hclge_dbg_item tm_qset_items[] = { -- Gitee From efe4e277ebba808a1de75fa47dbc4c76988e5868 Mon Sep 17 00:00:00 2001 From: Zhang Zekun Date: Fri, 11 Jul 2025 10:56:41 +0800 Subject: [PATCH 6/6] net: hns3: Use ARRAY_SIZE() to improve readability mainline inclusion from mainline-v6.13-rc7 commit 2cbece60a4af03803634abd1e840e513db48d42e category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICHMW9 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=2cbece60a4af03803634abd1e840e513db48d42e ---------------------------------------------------------------------- There is a helper function ARRAY_SIZE() to help calculating the u32 array size, and we don't need to do it mannually. So, let's use ARRAY_SIZE() to calculate the array size, and improve the code readability. Signed-off-by: Zhang Zekun Reviewed-by: Jijie Shao Link: https://patch.msgid.link/20240818052518.45489-1-zhangzekun11@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Donghua Huang --- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c index 637d83a400d3..809012bb2bc5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c @@ -134,17 +134,17 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, reg += hclgevf_reg_get_header(reg); /* fetching per-VF registers values from VF PCIe register space */ - reg_num = sizeof(cmdq_reg_addr_list) / sizeof(u32); + reg_num = ARRAY_SIZE(cmdq_reg_addr_list); reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg); for (i = 0; i < reg_num; i++) *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); - reg_num = sizeof(common_reg_addr_list) / sizeof(u32); + reg_num = ARRAY_SIZE(common_reg_addr_list); reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg); for (i = 0; i < reg_num; i++) *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); - reg_num = sizeof(ring_reg_addr_list) / sizeof(u32); + reg_num = ARRAY_SIZE(ring_reg_addr_list); for (j = 0; j < hdev->num_tqps; j++) { reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg); tqp = &hdev->htqp[j].q; @@ -154,7 +154,7 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, ring_reg_addr_list[i]); } - reg_num = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); + reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); for (j = 0; j < hdev->num_msi_used - 1; j++) { reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_num, reg); for (i = 0; i < reg_num; i++) -- Gitee