1 | There are some bugfix for the HNS3 ethernet driver | 1 | There are some bugfix for the HNS3 ethernet driver |
---|---|---|---|
2 | 2 | ||
3 | Hao Lan (1): | 3 | Jie Wang (1): |
4 | net: hns3: fix spelling mistake "reg_um" -> "reg_num" | 4 | net: hns3: add cond_resched() to hns3 ring buffer init process |
5 | |||
6 | Jian Shen (1): | ||
7 | net: hns3: store rx VLAN tag offload state for VF | ||
8 | 5 | ||
9 | Yonglong Liu (1): | 6 | Yonglong Liu (1): |
10 | net: hns3: fix a use of uninitialized variable problem | 7 | net: hns3: fix kernel crash problem in concurrent scenario |
11 | 8 | ||
12 | .../hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 9 | .../net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++++ |
13 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++----- | 10 | .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++ |
14 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | 11 | .../hisilicon/hns3/hns3pf/hclge_main.c | 21 ++++++++++++++----- |
15 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 12 | 3 files changed, 22 insertions(+), 5 deletions(-) |
16 | 4 files changed, 36 insertions(+), 21 deletions(-) | ||
17 | 13 | ||
18 | -- | 14 | -- |
19 | 2.33.0 | 15 | 2.30.0 | diff view generated by jsdifflib |
1 | From: Yonglong Liu <liuyonglong@huawei.com> | 1 | From: Yonglong Liu <liuyonglong@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | In hclge_add_fd_entry(), if the flow type is FLOW_EXT, and the data of | 3 | When link status change, the nic driver need to notify the roce |
4 | m_ext is all zero, then some members of the local variable "info" are | 4 | driver to handle this event, but at this time, the roce driver |
5 | not initialized. | 5 | may uninit, then cause kernel crash. |
6 | 6 | ||
7 | Fixes: 67b0e1428e2f ("net: hns3: add support for user-def data of flow director") | 7 | To fix the problem, when link status change, need to check |
8 | whether the roce registered, and when uninit, need to wait link | ||
9 | update finish. | ||
10 | |||
11 | Fixes: 45e92b7e4e27 ("net: hns3: add calling roce callback function when link status change") | ||
8 | Signed-off-by: Yonglong Liu <liuyonglong@huawei.com> | 12 | Signed-off-by: Yonglong Liu <liuyonglong@huawei.com> |
9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 13 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
10 | --- | 14 | --- |
11 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 15 | .../hisilicon/hns3/hns3pf/hclge_main.c | 21 ++++++++++++++----- |
12 | 1 file changed, 1 insertion(+), 1 deletion(-) | 16 | 1 file changed, 16 insertions(+), 5 deletions(-) |
13 | 17 | ||
14 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 18 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
15 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 20 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
17 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 21 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
18 | @@ -XXX,XX +XXX,XX @@ static int hclge_add_fd_entry(struct hnae3_handle *handle, | 22 | @@ -XXX,XX +XXX,XX @@ static void hclge_push_link_status(struct hclge_dev *hdev) |
19 | struct ethtool_rxnfc *cmd) | 23 | |
24 | static void hclge_update_link_status(struct hclge_dev *hdev) | ||
20 | { | 25 | { |
21 | struct hclge_vport *vport = hclge_get_vport(handle); | 26 | - struct hnae3_handle *rhandle = &hdev->vport[0].roce; |
22 | + struct hclge_fd_user_def_info info = {0}; | 27 | struct hnae3_handle *handle = &hdev->vport[0].nic; |
23 | struct hclge_dev *hdev = vport->back; | 28 | - struct hnae3_client *rclient = hdev->roce_client; |
24 | - struct hclge_fd_user_def_info info; | 29 | struct hnae3_client *client = hdev->nic_client; |
25 | u16 dst_vport_id = 0, q_index = 0; | 30 | int state; |
26 | struct ethtool_rx_flow_spec *fs; | 31 | int ret; |
27 | struct hclge_fd_rule *rule; | 32 | @@ -XXX,XX +XXX,XX @@ static void hclge_update_link_status(struct hclge_dev *hdev) |
33 | |||
34 | client->ops->link_status_change(handle, state); | ||
35 | hclge_config_mac_tnl_int(hdev, state); | ||
36 | - if (rclient && rclient->ops->link_status_change) | ||
37 | - rclient->ops->link_status_change(rhandle, state); | ||
38 | + | ||
39 | + if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) { | ||
40 | + struct hnae3_handle *rhandle = &hdev->vport[0].roce; | ||
41 | + struct hnae3_client *rclient = hdev->roce_client; | ||
42 | + | ||
43 | + if (rclient && rclient->ops->link_status_change) | ||
44 | + rclient->ops->link_status_change(rhandle, | ||
45 | + state); | ||
46 | + } | ||
47 | |||
48 | hclge_push_link_status(hdev); | ||
49 | } | ||
50 | @@ -XXX,XX +XXX,XX @@ static int hclge_init_client_instance(struct hnae3_client *client, | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | +static bool hclge_uninit_need_wait(struct hclge_dev *hdev) | ||
55 | +{ | ||
56 | + return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || | ||
57 | + test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state); | ||
58 | +} | ||
59 | + | ||
60 | static void hclge_uninit_client_instance(struct hnae3_client *client, | ||
61 | struct hnae3_ae_dev *ae_dev) | ||
62 | { | ||
63 | @@ -XXX,XX +XXX,XX @@ static void hclge_uninit_client_instance(struct hnae3_client *client, | ||
64 | |||
65 | if (hdev->roce_client) { | ||
66 | clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state); | ||
67 | - while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) | ||
68 | + while (hclge_uninit_need_wait(hdev)) | ||
69 | msleep(HCLGE_WAIT_RESET_DONE); | ||
70 | |||
71 | hdev->roce_client->ops->uninit_instance(&vport->roce, 0); | ||
28 | -- | 72 | -- |
29 | 2.33.0 | 73 | 2.30.0 | diff view generated by jsdifflib |
1 | From: Hao Lan <lanhao@huawei.com> | 1 | From: Jie Wang <wangjie125@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | There are spelling mistakes in hclgevf_get_regs. Fix them. | 3 | Currently hns3 ring buffer init process would hold cpu too long with big |
4 | Tx/Rx ring depth. This could cause soft lockup. | ||
4 | 5 | ||
5 | Signed-off-by: Hao Lan <lanhao@huawei.com> | 6 | So this patch adds cond_resched() to the process. Then cpu can break to |
7 | run other tasks instead of busy looping. | ||
8 | |||
9 | Fixes: a723fb8efe29 ("net: hns3: refine for set ring parameters") | ||
10 | Signed-off-by: Jie Wang <wangjie125@huawei.com> | ||
6 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 11 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
7 | --- | 12 | --- |
8 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 13 | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++++ |
9 | 1 file changed, 14 insertions(+), 13 deletions(-) | 14 | drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++ |
15 | 2 files changed, 6 insertions(+) | ||
10 | 16 | ||
11 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 17 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c |
12 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 19 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c |
14 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 20 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c |
15 | @@ -XXX,XX +XXX,XX @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | 21 | @@ -XXX,XX +XXX,XX @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring) |
16 | 22 | ret = hns3_alloc_and_attach_buffer(ring, i); | |
17 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 23 | if (ret) |
18 | struct hnae3_queue *tqp; | 24 | goto out_buffer_fail; |
19 | - int i, j, reg_um; | 25 | + |
20 | + int i, j, reg_num; | 26 | + if (!(i % HNS3_RESCHED_BD_NUM)) |
21 | u32 *reg = data; | 27 | + cond_resched(); |
22 | |||
23 | *version = hdev->fw_version; | ||
24 | reg += hclgevf_reg_get_header(reg); | ||
25 | |||
26 | /* fetching per-VF registers values from VF PCIe register space */ | ||
27 | - reg_um = ARRAY_SIZE(cmdq_reg_addr_list); | ||
28 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_um, reg); | ||
29 | - for (i = 0; i < reg_um; i++) | ||
30 | + reg_num = ARRAY_SIZE(cmdq_reg_addr_list); | ||
31 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg); | ||
32 | + for (i = 0; i < reg_num; i++) | ||
33 | *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); | ||
34 | |||
35 | - reg_um = ARRAY_SIZE(common_reg_addr_list); | ||
36 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_um, reg); | ||
37 | - for (i = 0; i < reg_um; i++) | ||
38 | + reg_num = ARRAY_SIZE(common_reg_addr_list); | ||
39 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg); | ||
40 | + for (i = 0; i < reg_num; i++) | ||
41 | *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); | ||
42 | |||
43 | - reg_um = ARRAY_SIZE(ring_reg_addr_list); | ||
44 | + reg_num = ARRAY_SIZE(ring_reg_addr_list); | ||
45 | for (j = 0; j < hdev->num_tqps; j++) { | ||
46 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); | ||
47 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg); | ||
48 | tqp = &hdev->htqp[j].q; | ||
49 | - for (i = 0; i < reg_um; i++) | ||
50 | + for (i = 0; i < reg_num; i++) | ||
51 | *reg++ = readl_relaxed(tqp->io_base - | ||
52 | HCLGEVF_TQP_REG_OFFSET + | ||
53 | ring_reg_addr_list[i]); | ||
54 | } | 28 | } |
55 | 29 | ||
56 | - reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); | 30 | return 0; |
57 | + reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); | 31 | @@ -XXX,XX +XXX,XX @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) |
58 | for (j = 0; j < hdev->num_msi_used - 1; j++) { | 32 | } |
59 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg); | 33 | |
60 | - for (i = 0; i < reg_um; i++) | 34 | u64_stats_init(&priv->ring[i].syncp); |
61 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, | 35 | + cond_resched(); |
62 | + reg_num, reg); | 36 | } |
63 | + for (i = 0; i < reg_num; i++) | 37 | |
64 | *reg++ = hclgevf_read_dev(&hdev->hw, | 38 | return 0; |
65 | tqp_intr_reg_addr_list[i] + | 39 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h |
66 | HCLGEVF_RING_INT_REG_OFFSET * j); | 40 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | ||
42 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | ||
43 | @@ -XXX,XX +XXX,XX @@ enum hns3_nic_state { | ||
44 | #define HNS3_CQ_MODE_EQE 1U | ||
45 | #define HNS3_CQ_MODE_CQE 0U | ||
46 | |||
47 | +#define HNS3_RESCHED_BD_NUM 1024 | ||
48 | + | ||
49 | enum hns3_pkt_l2t_type { | ||
50 | HNS3_L2_TYPE_UNICAST, | ||
51 | HNS3_L2_TYPE_MULTICAST, | ||
67 | -- | 52 | -- |
68 | 2.33.0 | 53 | 2.30.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Jian Shen <shenjian15@huawei.com> | ||
2 | 1 | ||
3 | The VF driver missed to store the rx VLAN tag strip state when | ||
4 | user change the rx VLAN tag offload state. And it will default | ||
5 | to enable the rx vlan tag strip when re-init VF device after | ||
6 | reset. So if user disable rx VLAN tag offload, and trig reset, | ||
7 | then the HW will still strip the VLAN tag from packet nad fill | ||
8 | into RX BD, but the VF driver will ignore it for rx VLAN tag | ||
9 | offload disabled. It may cause the rx VLAN tag dropped. | ||
10 | |||
11 | Fixes: b2641e2ad456 ("net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver") | ||
12 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
13 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
14 | --- | ||
15 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++++----- | ||
16 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | ||
17 | 2 files changed, 21 insertions(+), 7 deletions(-) | ||
18 | |||
19 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
22 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) | ||
24 | rtnl_unlock(); | ||
25 | } | ||
26 | |||
27 | -static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | ||
28 | +static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable) | ||
29 | { | ||
30 | - struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
31 | struct hclge_vf_to_pf_msg send_msg; | ||
32 | |||
33 | hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, | ||
34 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | ||
35 | return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); | ||
36 | } | ||
37 | |||
38 | +static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | ||
39 | +{ | ||
40 | + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
41 | + int ret; | ||
42 | + | ||
43 | + ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable); | ||
44 | + if (ret) | ||
45 | + return ret; | ||
46 | + | ||
47 | + hdev->rxvtag_strip_en = enable; | ||
48 | + return 0; | ||
49 | +} | ||
50 | + | ||
51 | static int hclgevf_reset_tqp(struct hnae3_handle *handle) | ||
52 | { | ||
53 | #define HCLGEVF_RESET_ALL_QUEUE_DONE 1U | ||
54 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) | ||
55 | tc_valid, tc_size); | ||
56 | } | ||
57 | |||
58 | -static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) | ||
59 | +static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev, | ||
60 | + bool rxvtag_strip_en) | ||
61 | { | ||
62 | struct hnae3_handle *nic = &hdev->nic; | ||
63 | int ret; | ||
64 | |||
65 | - ret = hclgevf_en_hw_strip_rxvtag(nic, true); | ||
66 | + ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en); | ||
67 | if (ret) { | ||
68 | dev_err(&hdev->pdev->dev, | ||
69 | "failed to enable rx vlan offload, ret = %d\n", ret); | ||
70 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) | ||
71 | if (ret) | ||
72 | return ret; | ||
73 | |||
74 | - ret = hclgevf_init_vlan_config(hdev); | ||
75 | + ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en); | ||
76 | if (ret) { | ||
77 | dev_err(&hdev->pdev->dev, | ||
78 | "failed(%d) to initialize VLAN config\n", ret); | ||
79 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) | ||
80 | goto err_config; | ||
81 | } | ||
82 | |||
83 | - ret = hclgevf_init_vlan_config(hdev); | ||
84 | + ret = hclgevf_init_vlan_config(hdev, true); | ||
85 | if (ret) { | ||
86 | dev_err(&hdev->pdev->dev, | ||
87 | "failed(%d) to initialize VLAN config\n", ret); | ||
88 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
91 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
92 | @@ -XXX,XX +XXX,XX @@ struct hclgevf_dev { | ||
93 | u16 *vector_status; | ||
94 | int *vector_irq; | ||
95 | |||
96 | - bool gro_en; | ||
97 | + u32 gro_en :1; | ||
98 | + u32 rxvtag_strip_en :1; | ||
99 | |||
100 | unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; | ||
101 | |||
102 | -- | ||
103 | 2.33.0 | diff view generated by jsdifflib |