From c2002cc80d891d48a81adaae8f200b9029ca4743 Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Sat, 18 Jan 2025 17:47:41 +0800 Subject: [PATCH 1/4] net: hns3: fix oops when unload drivers paralleling maillist inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBQKQF CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=92e599577377 ---------------------------------------------------------------------- When unload hclge driver, it tries to disable sriov first for each ae_dev node from hnae3_ae_dev_list. If user unloads hns3 driver at the time, because it removes all the ae_dev nodes, and it may cause oops. But we can't simply use hnae3_common_lock for this. Because in the process flow of pci_disable_sriov(), it will trigger the remove flow of VF, which will also take hnae3_common_lock. To fixes it, introduce a new mutex to protect the unload process. Fixes: 0dd8a25f355b ("net: hns3: disable sriov before unload hclge layer") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao Link: https://patch.msgid.link/20250118094741.3046663-1-shaojijie@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Hao Chen --- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 15 +++++++++++++++ drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 ++ .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 ++ 5 files changed, 23 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c index 82ce3f5744a0..0a6433cc6793 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -37,6 +37,21 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare); */ static DEFINE_MUTEX(hnae3_common_lock); +/* ensure the drivers being unloaded one by one */ +static DEFINE_MUTEX(hnae3_unload_lock); + +void hnae3_acquire_unload_lock(void) +{ + mutex_lock(&hnae3_unload_lock); +} +EXPORT_SYMBOL(hnae3_acquire_unload_lock); + +void hnae3_release_unload_lock(void) +{ + mutex_unlock(&hnae3_unload_lock); +} +EXPORT_SYMBOL(hnae3_release_unload_lock); + static bool hnae3_client_match(enum hnae3_client_type client_type) { if (client_type == HNAE3_CLIENT_KNIC || diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 922f262f33c9..2f0b375d5c41 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -1106,4 +1106,6 @@ int hnae3_register_client(struct hnae3_client *client); void hnae3_set_client_init_flag(struct hnae3_client *client, struct hnae3_ae_dev *ae_dev, unsigned int inited); +void hnae3_acquire_unload_lock(void); +void hnae3_release_unload_lock(void); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 742152e3f494..0f25d4fa94dd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -6527,12 +6527,14 @@ module_init(hns3_init_module); */ static void __exit hns3_exit_module(void) { + hnae3_acquire_unload_lock(); #ifdef CONFIG_HNS3_UBL unregister_ipaddr_notifier(); #endif pci_unregister_driver(&hns3_driver); hnae3_unregister_client(&client); hns3_dbg_unregister_debugfs(); + hnae3_release_unload_lock(); } module_exit(hns3_exit_module); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index aceb28acf9ca..20a789d17b4f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -13842,9 +13842,11 @@ static int hclge_init(void) static void hclge_exit(void) { + hnae3_acquire_unload_lock(); hnae3_unregister_ae_algo_prepare(&ae_algo); hnae3_unregister_ae_algo(&ae_algo); destroy_workqueue(hclge_wq); + hnae3_release_unload_lock(); } module_init(hclge_init); module_exit(hclge_exit); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 050eeec02e56..17048df81869 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -3735,8 +3735,10 @@ static int hclgevf_init(void) static void hclgevf_exit(void) { + hnae3_acquire_unload_lock(); hnae3_unregister_ae_algo(&ae_algovf); destroy_workqueue(hclgevf_wq); + hnae3_release_unload_lock(); } module_init(hclgevf_init); module_exit(hclgevf_exit); -- Gitee From a8ce380befee5c9bc012a95f8ea56999b4e1a17d Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Thu, 17 Oct 2024 16:58:55 +0800 Subject: [PATCH 2/4] net: hns3: add mac tunnel number query driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBQKQF CVE: NA ---------------------------------------------------------------------- The mac tunnel number was missed when query the dev_info by debugfs, so add it. Fixes: c929bc2ac36e ("net: hns3: refactor dev capability and dev spec of debugfs") Signed-off-by: Jian Shen Signed-off-by: Hao Chen --- drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 465b168f7e89..c94c2c217156 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -1109,6 +1109,8 @@ hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos) dev->watchdog_timeo / HZ); *pos += scnprintf(buf + *pos, len - *pos, "Hilink Version: %u\n", dev_specs->hilink_version); + pos += scnprintf(buf + *pos, len - *pos, "mac tunnel number: %u\n", + dev_specs->tnl_num); *pos += scnprintf(buf + *pos, len - *pos, "total rx buffer size: %u\n", dev_specs->total_rx_buffer_size); *pos += scnprintf(buf + *pos, len - *pos, "min rx buffer size per tc: %u\n", -- Gitee From bcf0b1b9ffebaf1405644b1e401e5f1984579fb1 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Mon, 10 Mar 2025 14:22:50 +0800 Subject: [PATCH 3/4] net: hns3: Revert "net: hns3: add command queue trace for hns3" driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBQKQF CVE: NA ---------------------------------------------------------------------- This reverts commit 994cd2e0768a9cdec26bda0311507c255f5fe4b1. Signed-off-by: Hao Chen --- .../hns3/hns3_common/hclge_comm_cmd.c | 18 ---- .../hns3/hns3_common/hclge_comm_cmd.h | 14 +-- .../hisilicon/hns3/hns3pf/hclge_main.c | 45 --------- .../hisilicon/hns3/hns3pf/hclge_trace.h | 94 ------------------- .../hisilicon/hns3/hns3vf/hclgevf_main.c | 40 -------- .../hisilicon/hns3/hns3vf/hclgevf_trace.h | 50 ---------- 6 files changed, 1 insertion(+), 260 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index c4d62dbd71a5..e575c8c75473 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -474,14 +474,10 @@ static int hclge_comm_cmd_check_result(struct hclge_comm_hw *hw, int hclge_comm_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, int num) { - bool is_special = hclge_comm_is_special_opcode(desc->opcode); struct hclge_comm_cmq_ring *csq = &hw->cmq.csq; int ret; int ntc; - if (hw->cmq.ops.trace_cmd_send) - hw->cmq.ops.trace_cmd_send(hw, desc, num, is_special); - spin_lock_bh(&hw->cmq.csq.lock); if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state)) { @@ -515,9 +511,6 @@ int hclge_comm_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, spin_unlock_bh(&hw->cmq.csq.lock); - if (hw->cmq.ops.trace_cmd_get) - hw->cmq.ops.trace_cmd_get(hw, desc, num, is_special); - return ret; } @@ -595,17 +588,6 @@ int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw) return ret; } -void hclge_comm_cmd_init_ops(struct hclge_comm_hw *hw, - const struct hclge_comm_cmq_ops *ops) -{ - struct hclge_comm_cmq *cmdq = &hw->cmq; - - if (ops) { - cmdq->ops.trace_cmd_send = ops->trace_cmd_send; - cmdq->ops.trace_cmd_get = ops->trace_cmd_get; - } -} - int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw, u32 *fw_version, bool is_pf, unsigned long reset_pending) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index 9264a17c37cb..a1c5c3171cdd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -447,22 +447,11 @@ enum hclge_comm_cmd_status { HCLGE_COMM_ERR_CSQ_ERROR = -3, }; -struct hclge_comm_hw; -struct hclge_comm_cmq_ops { - void (*trace_cmd_send)(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int num, bool is_special); - void (*trace_cmd_get)(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int num, bool is_special); -}; - struct hclge_comm_cmq { struct hclge_comm_cmq_ring csq; struct hclge_comm_cmq_ring crq; u16 tx_timeout; enum hclge_comm_cmd_status last_status; - struct hclge_comm_cmq_ops ops; }; struct hclge_comm_hw { @@ -509,6 +498,5 @@ int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw); int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw, u32 *fw_version, bool is_pf, unsigned long reset_pending); -void hclge_comm_cmd_init_ops(struct hclge_comm_hw *hw, - const struct hclge_comm_cmq_ops *ops); + #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 20a789d17b4f..34b9572e9449 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -42,8 +42,6 @@ #include "hclge_unic_addr.h" #endif -#include "hclge_trace.h" - #define HCLGE_NAME "hclge" #define HCLGE_BUF_SIZE_UNIT 256U @@ -417,48 +415,6 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) return hclge_comm_cmd_send(&hw->hw, desc, num); } -static void hclge_trace_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, - int num, bool is_special) -{ - int i; - - trace_hclge_pf_cmd_send(hw, desc, 0, num); - - if (!is_special) { - for (i = 1; i < num; i++) - trace_hclge_pf_cmd_send(hw, &desc[i], i, num); - } else { - for (i = 1; i < num; i++) - trace_hclge_pf_special_cmd_send(hw, (u32 *)&desc[i], - i, num); - } -} - -static void hclge_trace_cmd_get(struct hclge_comm_hw *hw, struct hclge_desc *desc, - int num, bool is_special) -{ - int i; - - if (!HCLGE_COMM_SEND_SYNC(le16_to_cpu(desc->flag))) - return; - - trace_hclge_pf_cmd_get(hw, desc, 0, num); - - if (!is_special) { - for (i = 1; i < num; i++) - trace_hclge_pf_cmd_get(hw, &desc[i], i, num); - } else { - for (i = 1; i < num; i++) - trace_hclge_pf_special_cmd_get(hw, (u32 *)&desc[i], - i, num); - } -} - -static const struct hclge_comm_cmq_ops hclge_cmq_ops = { - .trace_cmd_send = hclge_trace_cmd_send, - .trace_cmd_get = hclge_trace_cmd_get, -}; - static int hclge_mac_update_stats_defective(struct hclge_dev *hdev) { #define HCLGE_MAC_CMD_NUM 21 @@ -12609,7 +12565,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) goto err_pci_uninit; /* Firmware command initialize */ - hclge_comm_cmd_init_ops(&hdev->hw.hw, &hclge_cmq_ops); ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, true, hdev->reset_pending); if (ret) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h index d8afc2a052dc..f3cd5a376eca 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h @@ -10,7 +10,6 @@ #include -#define PF_DESC_LEN (sizeof(struct hclge_desc) / sizeof(u32)) #define PF_GET_MBX_LEN (sizeof(struct hclge_mbx_vf_to_pf_cmd) / sizeof(u32)) #define PF_SEND_MBX_LEN (sizeof(struct hclge_mbx_pf_to_vf_cmd) / sizeof(u32)) @@ -78,99 +77,6 @@ TRACE_EVENT(hclge_pf_mbx_send, ) ); -DECLARE_EVENT_CLASS(hclge_pf_cmd_template, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num), - - TP_STRUCT__entry(__field(u16, opcode) - __field(u16, flag) - __field(u16, retval) - __field(u16, rsv) - __field(int, index) - __field(int, num) - __string(pciname, pci_name(hw->cmq.csq.pdev)) - __array(u32, data, HCLGE_DESC_DATA_LEN)), - - TP_fast_assign(int i; - __entry->opcode = le16_to_cpu(desc->opcode); - __entry->flag = le16_to_cpu(desc->flag); - __entry->retval = le16_to_cpu(desc->retval); - __entry->rsv = le16_to_cpu(desc->rsv); - __entry->index = index; - __entry->num = num; - __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); - for (i = 0; i < HCLGE_DESC_DATA_LEN; i++) - __entry->data[i] = le32_to_cpu(desc->data[i]);), - - TP_printk("%s opcode:0x%04x %d-%d flag:0x%04x retval:0x%04x rsv:0x%04x data:%s", - __get_str(pciname), __entry->opcode, - __entry->index, __entry->num, - __entry->flag, __entry->retval, __entry->rsv, - __print_array(__entry->data, - HCLGE_DESC_DATA_LEN, sizeof(u32))) -); - -DEFINE_EVENT(hclge_pf_cmd_template, hclge_pf_cmd_send, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num) -); - -DEFINE_EVENT(hclge_pf_cmd_template, hclge_pf_cmd_get, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num) -); - -DECLARE_EVENT_CLASS(hclge_pf_special_cmd_template, - TP_PROTO(struct hclge_comm_hw *hw, - u32 *data, - int index, - int num), - TP_ARGS(hw, data, index, num), - - TP_STRUCT__entry(__field(int, index) - __field(int, num) - __string(pciname, pci_name(hw->cmq.csq.pdev)) - __array(u32, data, PF_DESC_LEN)), - - TP_fast_assign(int i; - __entry->index = index; - __entry->num = num; - __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); - for (i = 0; i < PF_DESC_LEN; i++) - __entry->data[i] = le32_to_cpu(data[i]); - ), - - TP_printk("%s %d-%d data:%s", - __get_str(pciname), - __entry->index, __entry->num, - __print_array(__entry->data, - PF_DESC_LEN, sizeof(u32))) -); - -DEFINE_EVENT(hclge_pf_special_cmd_template, hclge_pf_special_cmd_send, - TP_PROTO(struct hclge_comm_hw *hw, - u32 *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num)); - -DEFINE_EVENT(hclge_pf_special_cmd_template, hclge_pf_special_cmd_get, - TP_PROTO(struct hclge_comm_hw *hw, - u32 *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num) -); - #endif /* _HCLGE_TRACE_H_ */ /* This must be outside ifdef _HCLGE_TRACE_H */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 17048df81869..ef13ba549ef3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -20,7 +20,6 @@ #include "hclgevf_unic_guid.h" #include "hclgevf_unic_addr.h" #endif -#include "hclgevf_trace.h" #include "hclgevf_dcb.h" #define HCLGEVF_NAME "hclgevf" @@ -66,42 +65,6 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclge_desc *desc, int num) return hclge_comm_cmd_send(&hw->hw, desc, num); } -static void hclgevf_trace_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, - int num, bool is_special) -{ - int i; - - trace_hclge_vf_cmd_send(hw, desc, 0, num); - - if (is_special) - return; - - for (i = 1; i < num; i++) - trace_hclge_vf_cmd_send(hw, &desc[i], i, num); -} - -static void hclgevf_trace_cmd_get(struct hclge_comm_hw *hw, struct hclge_desc *desc, - int num, bool is_special) -{ - int i; - - if (!HCLGE_COMM_SEND_SYNC(le16_to_cpu(desc->flag))) - return; - - trace_hclge_vf_cmd_get(hw, desc, 0, num); - - if (is_special) - return; - - for (i = 1; i < num; i++) - trace_hclge_vf_cmd_get(hw, &desc[i], i, num); -} - -static const struct hclge_comm_cmq_ops hclgevf_cmq_ops = { - .trace_cmd_send = hclgevf_trace_cmd_send, - .trace_cmd_get = hclgevf_trace_cmd_get, -}; - void hclgevf_arq_init(struct hclgevf_dev *hdev) { struct hclge_comm_cmq *cmdq = &hdev->hw.hw.cmq; @@ -3155,7 +3118,6 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) } hclgevf_arq_init(hdev); - ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, false, hdev->reset_pending); @@ -3214,8 +3176,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) goto err_cmd_queue_init; hclgevf_arq_init(hdev); - - hclge_comm_cmd_init_ops(&hdev->hw.hw, &hclgevf_cmq_ops); ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, false, hdev->reset_pending); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h index e2e3a2602b6a..b259e95dd53c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h @@ -77,56 +77,6 @@ TRACE_EVENT(hclge_vf_mbx_send, ) ); -DECLARE_EVENT_CLASS(hclge_vf_cmd_template, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - - TP_ARGS(hw, desc, index, num), - - TP_STRUCT__entry(__field(u16, opcode) - __field(u16, flag) - __field(u16, retval) - __field(u16, rsv) - __field(int, index) - __field(int, num) - __string(pciname, pci_name(hw->cmq.csq.pdev)) - __array(u32, data, HCLGE_DESC_DATA_LEN)), - - TP_fast_assign(int i; - __entry->opcode = le16_to_cpu(desc->opcode); - __entry->flag = le16_to_cpu(desc->flag); - __entry->retval = le16_to_cpu(desc->retval); - __entry->rsv = le16_to_cpu(desc->rsv); - __entry->index = index; - __entry->num = num; - __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); - for (i = 0; i < HCLGE_DESC_DATA_LEN; i++) - __entry->data[i] = le32_to_cpu(desc->data[i]);), - - TP_printk("%s opcode:0x%04x %d-%d flag:0x%04x retval:0x%04x rsv:0x%04x data:%s", - __get_str(pciname), __entry->opcode, - __entry->index, __entry->num, - __entry->flag, __entry->retval, __entry->rsv, - __print_array(__entry->data, - HCLGE_DESC_DATA_LEN, sizeof(u32))) -); - -DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_send, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num)); - -DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_get, - TP_PROTO(struct hclge_comm_hw *hw, - struct hclge_desc *desc, - int index, - int num), - TP_ARGS(hw, desc, index, num)); - #endif /* _HCLGEVF_TRACE_H_ */ /* This must be outside ifdef _HCLGEVF_TRACE_H */ -- Gitee From ec796ec9b287766009024862601ec5af12044dba Mon Sep 17 00:00:00 2001 From: Hao Lan Date: Wed, 10 Apr 2024 20:53:51 +0800 Subject: [PATCH 4/4] net: hns3: add command queue trace for hns3 maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBQKQF CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=92e599577377 ---------------------------------------------------------------------- Add support to dump command queue trace for hns3. Signed-off-by: Hao Lan Signed-off-by: Jijie Shao Link: https://lore.kernel.org/r/20240410125354.2177067-2-shaojijie@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Hao Chen --- .../hns3/hns3_common/hclge_comm_cmd.c | 18 ++++ .../hns3/hns3_common/hclge_comm_cmd.h | 14 ++- .../hisilicon/hns3/hns3pf/hclge_main.c | 44 +++++++++ .../hisilicon/hns3/hns3pf/hclge_trace.h | 94 +++++++++++++++++++ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 40 ++++++++ .../hisilicon/hns3/hns3vf/hclgevf_trace.h | 50 ++++++++++ 6 files changed, 259 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index e575c8c75473..76b4a97e9250 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -474,10 +474,14 @@ static int hclge_comm_cmd_check_result(struct hclge_comm_hw *hw, int hclge_comm_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, int num) { + bool is_special = hclge_comm_is_special_opcode(le16_to_cpu(desc->opcode)); struct hclge_comm_cmq_ring *csq = &hw->cmq.csq; int ret; int ntc; + if (hw->cmq.ops.trace_cmd_send) + hw->cmq.ops.trace_cmd_send(hw, desc, num, is_special); + spin_lock_bh(&hw->cmq.csq.lock); if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hw->comm_state)) { @@ -511,6 +515,9 @@ int hclge_comm_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, spin_unlock_bh(&hw->cmq.csq.lock); + if (hw->cmq.ops.trace_cmd_get) + hw->cmq.ops.trace_cmd_get(hw, desc, num, is_special); + return ret; } @@ -588,6 +595,17 @@ int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw) return ret; } +void hclge_comm_cmd_init_ops(struct hclge_comm_hw *hw, + const struct hclge_comm_cmq_ops *ops) +{ + struct hclge_comm_cmq *cmdq = &hw->cmq; + + if (ops) { + cmdq->ops.trace_cmd_send = ops->trace_cmd_send; + cmdq->ops.trace_cmd_get = ops->trace_cmd_get; + } +} + int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw, u32 *fw_version, bool is_pf, unsigned long reset_pending) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index a1c5c3171cdd..9264a17c37cb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -447,11 +447,22 @@ enum hclge_comm_cmd_status { HCLGE_COMM_ERR_CSQ_ERROR = -3, }; +struct hclge_comm_hw; +struct hclge_comm_cmq_ops { + void (*trace_cmd_send)(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int num, bool is_special); + void (*trace_cmd_get)(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int num, bool is_special); +}; + struct hclge_comm_cmq { struct hclge_comm_cmq_ring csq; struct hclge_comm_cmq_ring crq; u16 tx_timeout; enum hclge_comm_cmd_status last_status; + struct hclge_comm_cmq_ops ops; }; struct hclge_comm_hw { @@ -498,5 +509,6 @@ int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw); int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw, u32 *fw_version, bool is_pf, unsigned long reset_pending); - +void hclge_comm_cmd_init_ops(struct hclge_comm_hw *hw, + const struct hclge_comm_cmq_ops *ops); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 34b9572e9449..458c39c8fa6f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -41,6 +41,7 @@ #include "hclge_unic_guid.h" #include "hclge_unic_addr.h" #endif +#include "hclge_trace.h" #define HCLGE_NAME "hclge" @@ -415,6 +416,48 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) return hclge_comm_cmd_send(&hw->hw, desc, num); } +static void hclge_trace_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, + int num, bool is_special) +{ + int i; + + trace_hclge_pf_cmd_send(hw, desc, 0, num); + + if (!is_special) { + for (i = 1; i < num; i++) + trace_hclge_pf_cmd_send(hw, &desc[i], i, num); + } else { + for (i = 1; i < num; i++) + trace_hclge_pf_special_cmd_send(hw, (__le32 *)&desc[i], + i, num); + } +} + +static void hclge_trace_cmd_get(struct hclge_comm_hw *hw, struct hclge_desc *desc, + int num, bool is_special) +{ + int i; + + if (!HCLGE_COMM_SEND_SYNC(le16_to_cpu(desc->flag))) + return; + + trace_hclge_pf_cmd_get(hw, desc, 0, num); + + if (!is_special) { + for (i = 1; i < num; i++) + trace_hclge_pf_cmd_get(hw, &desc[i], i, num); + } else { + for (i = 1; i < num; i++) + trace_hclge_pf_special_cmd_get(hw, (__le32 *)&desc[i], + i, num); + } +} + +static const struct hclge_comm_cmq_ops hclge_cmq_ops = { + .trace_cmd_send = hclge_trace_cmd_send, + .trace_cmd_get = hclge_trace_cmd_get, +}; + static int hclge_mac_update_stats_defective(struct hclge_dev *hdev) { #define HCLGE_MAC_CMD_NUM 21 @@ -12565,6 +12608,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) goto err_pci_uninit; /* Firmware command initialize */ + hclge_comm_cmd_init_ops(&hdev->hw.hw, &hclge_cmq_ops); ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, true, hdev->reset_pending); if (ret) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h index f3cd5a376eca..7e47f0c21d88 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h @@ -10,6 +10,7 @@ #include +#define PF_DESC_LEN (sizeof(struct hclge_desc) / sizeof(u32)) #define PF_GET_MBX_LEN (sizeof(struct hclge_mbx_vf_to_pf_cmd) / sizeof(u32)) #define PF_SEND_MBX_LEN (sizeof(struct hclge_mbx_pf_to_vf_cmd) / sizeof(u32)) @@ -77,6 +78,99 @@ TRACE_EVENT(hclge_pf_mbx_send, ) ); +DECLARE_EVENT_CLASS(hclge_pf_cmd_template, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num), + + TP_STRUCT__entry(__field(u16, opcode) + __field(u16, flag) + __field(u16, retval) + __field(u16, rsv) + __field(int, index) + __field(int, num) + __string(pciname, pci_name(hw->cmq.csq.pdev)) + __array(u32, data, HCLGE_DESC_DATA_LEN)), + + TP_fast_assign(int i; + __entry->opcode = le16_to_cpu(desc->opcode); + __entry->flag = le16_to_cpu(desc->flag); + __entry->retval = le16_to_cpu(desc->retval); + __entry->rsv = le16_to_cpu(desc->rsv); + __entry->index = index; + __entry->num = num; + __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); + for (i = 0; i < HCLGE_DESC_DATA_LEN; i++) + __entry->data[i] = le32_to_cpu(desc->data[i]);), + + TP_printk("%s opcode:0x%04x %d-%d flag:0x%04x retval:0x%04x rsv:0x%04x data:%s", + __get_str(pciname), __entry->opcode, + __entry->index, __entry->num, + __entry->flag, __entry->retval, __entry->rsv, + __print_array(__entry->data, + HCLGE_DESC_DATA_LEN, sizeof(u32))) +); + +DEFINE_EVENT(hclge_pf_cmd_template, hclge_pf_cmd_send, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num) +); + +DEFINE_EVENT(hclge_pf_cmd_template, hclge_pf_cmd_get, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num) +); + +DECLARE_EVENT_CLASS(hclge_pf_special_cmd_template, + TP_PROTO(struct hclge_comm_hw *hw, + __le32 *data, + int index, + int num), + TP_ARGS(hw, data, index, num), + + TP_STRUCT__entry(__field(int, index) + __field(int, num) + __string(pciname, pci_name(hw->cmq.csq.pdev)) + __array(u32, data, PF_DESC_LEN)), + + TP_fast_assign(int i; + __entry->index = index; + __entry->num = num; + __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); + for (i = 0; i < PF_DESC_LEN; i++) + __entry->data[i] = le32_to_cpu(data[i]); + ), + + TP_printk("%s %d-%d data:%s", + __get_str(pciname), + __entry->index, __entry->num, + __print_array(__entry->data, + PF_DESC_LEN, sizeof(u32))) +); + +DEFINE_EVENT(hclge_pf_special_cmd_template, hclge_pf_special_cmd_send, + TP_PROTO(struct hclge_comm_hw *hw, + __le32 *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num)); + +DEFINE_EVENT(hclge_pf_special_cmd_template, hclge_pf_special_cmd_get, + TP_PROTO(struct hclge_comm_hw *hw, + __le32 *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num) +); + #endif /* _HCLGE_TRACE_H_ */ /* This must be outside ifdef _HCLGE_TRACE_H */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index ef13ba549ef3..97a5605f42e1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -21,6 +21,7 @@ #include "hclgevf_unic_addr.h" #endif #include "hclgevf_dcb.h" +#include "hclgevf_trace.h" #define HCLGEVF_NAME "hclgevf" @@ -65,6 +66,42 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclge_desc *desc, int num) return hclge_comm_cmd_send(&hw->hw, desc, num); } +static void hclgevf_trace_cmd_send(struct hclge_comm_hw *hw, struct hclge_desc *desc, + int num, bool is_special) +{ + int i; + + trace_hclge_vf_cmd_send(hw, desc, 0, num); + + if (is_special) + return; + + for (i = 1; i < num; i++) + trace_hclge_vf_cmd_send(hw, &desc[i], i, num); +} + +static void hclgevf_trace_cmd_get(struct hclge_comm_hw *hw, struct hclge_desc *desc, + int num, bool is_special) +{ + int i; + + if (!HCLGE_COMM_SEND_SYNC(le16_to_cpu(desc->flag))) + return; + + trace_hclge_vf_cmd_get(hw, desc, 0, num); + + if (is_special) + return; + + for (i = 1; i < num; i++) + trace_hclge_vf_cmd_get(hw, &desc[i], i, num); +} + +static const struct hclge_comm_cmq_ops hclgevf_cmq_ops = { + .trace_cmd_send = hclgevf_trace_cmd_send, + .trace_cmd_get = hclgevf_trace_cmd_get, +}; + void hclgevf_arq_init(struct hclgevf_dev *hdev) { struct hclge_comm_cmq *cmdq = &hdev->hw.hw.cmq; @@ -3118,6 +3155,7 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) } hclgevf_arq_init(hdev); + ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, false, hdev->reset_pending); @@ -3176,6 +3214,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) goto err_cmd_queue_init; hclgevf_arq_init(hdev); + + hclge_comm_cmd_init_ops(&hdev->hw.hw, &hclgevf_cmq_ops); ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version, false, hdev->reset_pending); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h index b259e95dd53c..e2e3a2602b6a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h @@ -77,6 +77,56 @@ TRACE_EVENT(hclge_vf_mbx_send, ) ); +DECLARE_EVENT_CLASS(hclge_vf_cmd_template, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + + TP_ARGS(hw, desc, index, num), + + TP_STRUCT__entry(__field(u16, opcode) + __field(u16, flag) + __field(u16, retval) + __field(u16, rsv) + __field(int, index) + __field(int, num) + __string(pciname, pci_name(hw->cmq.csq.pdev)) + __array(u32, data, HCLGE_DESC_DATA_LEN)), + + TP_fast_assign(int i; + __entry->opcode = le16_to_cpu(desc->opcode); + __entry->flag = le16_to_cpu(desc->flag); + __entry->retval = le16_to_cpu(desc->retval); + __entry->rsv = le16_to_cpu(desc->rsv); + __entry->index = index; + __entry->num = num; + __assign_str(pciname, pci_name(hw->cmq.csq.pdev)); + for (i = 0; i < HCLGE_DESC_DATA_LEN; i++) + __entry->data[i] = le32_to_cpu(desc->data[i]);), + + TP_printk("%s opcode:0x%04x %d-%d flag:0x%04x retval:0x%04x rsv:0x%04x data:%s", + __get_str(pciname), __entry->opcode, + __entry->index, __entry->num, + __entry->flag, __entry->retval, __entry->rsv, + __print_array(__entry->data, + HCLGE_DESC_DATA_LEN, sizeof(u32))) +); + +DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_send, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num)); + +DEFINE_EVENT(hclge_vf_cmd_template, hclge_vf_cmd_get, + TP_PROTO(struct hclge_comm_hw *hw, + struct hclge_desc *desc, + int index, + int num), + TP_ARGS(hw, desc, index, num)); + #endif /* _HCLGEVF_TRACE_H_ */ /* This must be outside ifdef _HCLGEVF_TRACE_H */ -- Gitee