1 | There are some bugfix for the HNS3 ethernet driver | 1 | There's a series of bugfix that's been accepted: |
---|---|---|---|
2 | https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=d80a3091308491455b6501b1c4b68698c4a7cd24 | ||
2 | 3 | ||
3 | Hao Lan (1): | 4 | However, The series is making the driver poke into IOMMU internals instead of |
4 | net: hns3: fix spelling mistake "reg_um" -> "reg_num" | 5 | implementing appropriate IOMMU workarounds. After discussion, the series was reverted: |
6 | https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=249cfa318fb1b77eb726c2ff4f74c9685f04e568 | ||
5 | 7 | ||
6 | Jian Shen (1): | 8 | But only two patches are related to the IOMMU. |
7 | net: hns3: store rx VLAN tag offload state for VF | 9 | Other patches involve only the modification of the driver. |
10 | This series resends other patches. | ||
8 | 11 | ||
9 | Yonglong Liu (1): | 12 | --- |
10 | net: hns3: fix a use of uninitialized variable problem | 13 | ChangeLog: |
14 | v2 RESEND -> v3: | ||
15 | - Add one comment, suggested by Michal Swiatkowski. | ||
16 | v2 RESEND: https://lore.kernel.org/all/20241217010839.1742227-1-shaojijie@huawei.com/ | ||
17 | v2 -> v2 RESEND: | ||
18 | - Send to net instead of net-next. | ||
19 | v2: https://lore.kernel.org/all/20241216132346.1197079-1-shaojijie@huawei.com/ | ||
20 | v1 -> v2: | ||
21 | - Fix a data inconsistency issue caused by simultaneous access of multiple readers, | ||
22 | suggested by Jakub. | ||
23 | v1: https://lore.kernel.org/all/20241107133023.3813095-1-shaojijie@huawei.com/ | ||
24 | --- | ||
25 | Hao Lan (4): | ||
26 | net: hns3: fixed reset failure issues caused by the incorrect reset | ||
27 | type | ||
28 | net: hns3: fix missing features due to dev->features configuration too | ||
29 | early | ||
30 | net: hns3: Resolved the issue that the debugfs query result is | ||
31 | inconsistent. | ||
32 | net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds | ||
33 | issue | ||
11 | 34 | ||
12 | .../hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 35 | Jian Shen (2): |
13 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++----- | 36 | net: hns3: don't auto enable misc vector |
14 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | 37 | net: hns3: initialize reset_timer before hclgevf_misc_irq_init() |
15 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 38 | |
16 | 4 files changed, 36 insertions(+), 21 deletions(-) | 39 | Jie Wang (1): |
40 | net: hns3: fix kernel crash when 1588 is sent on HIP08 devices | ||
41 | |||
42 | drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 - | ||
43 | .../ethernet/hisilicon/hns3/hns3_debugfs.c | 96 ++++++------------- | ||
44 | .../net/ethernet/hisilicon/hns3/hns3_enet.c | 1 - | ||
45 | .../hisilicon/hns3/hns3pf/hclge_main.c | 45 +++++++-- | ||
46 | .../hisilicon/hns3/hns3pf/hclge_ptp.c | 3 + | ||
47 | .../hisilicon/hns3/hns3pf/hclge_regs.c | 9 +- | ||
48 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 41 ++++++-- | ||
49 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 9 +- | ||
50 | 8 files changed, 114 insertions(+), 93 deletions(-) | ||
17 | 51 | ||
18 | -- | 52 | -- |
19 | 2.33.0 | 53 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Hao Lan <lanhao@huawei.com> | |
2 | |||
3 | When a reset type that is not supported by the driver is input, a reset | ||
4 | pending flag bit of the HNAE3_NONE_RESET type is generated in | ||
5 | reset_pending. The driver does not have a mechanism to clear this type | ||
6 | of error. As a result, the driver considers that the reset is not | ||
7 | complete. This patch provides a mechanism to clear the | ||
8 | HNAE3_NONE_RESET flag and the parameter of | ||
9 | hnae3_ae_ops.set_default_reset_request is verified. | ||
10 | |||
11 | The error message: | ||
12 | hns3 0000:39:01.0: cmd failed -16 | ||
13 | hns3 0000:39:01.0: hclge device re-init failed, VF is disabled! | ||
14 | hns3 0000:39:01.0: failed to reset VF stack | ||
15 | hns3 0000:39:01.0: failed to reset VF(4) | ||
16 | hns3 0000:39:01.0: prepare reset(2) wait done | ||
17 | hns3 0000:39:01.0 eth4: already uninitialized | ||
18 | |||
19 | Use the crash tool to view struct hclgevf_dev: | ||
20 | struct hclgevf_dev { | ||
21 | ... | ||
22 | default_reset_request = 0x20, | ||
23 | reset_level = HNAE3_NONE_RESET, | ||
24 | reset_pending = 0x100, | ||
25 | reset_type = HNAE3_NONE_RESET, | ||
26 | ... | ||
27 | }; | ||
28 | |||
29 | Fixes: 720bd5837e37 ("net: hns3: add set_default_reset_request in the hnae3_ae_ops") | ||
30 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
31 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
32 | --- | ||
33 | .../hisilicon/hns3/hns3pf/hclge_main.c | 33 ++++++++++++++-- | ||
34 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 38 ++++++++++++++++--- | ||
35 | 2 files changed, 61 insertions(+), 10 deletions(-) | ||
36 | |||
37 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
40 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, | ||
42 | return ret; | ||
43 | } | ||
44 | |||
45 | +static void hclge_set_reset_pending(struct hclge_dev *hdev, | ||
46 | + enum hnae3_reset_type reset_type) | ||
47 | +{ | ||
48 | + /* When an incorrect reset type is executed, the get_reset_level | ||
49 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | ||
50 | + * type do not need to pending. | ||
51 | + */ | ||
52 | + if (reset_type != HNAE3_NONE_RESET) | ||
53 | + set_bit(reset_type, &hdev->reset_pending); | ||
54 | +} | ||
55 | + | ||
56 | static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
57 | { | ||
58 | u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg; | ||
59 | @@ -XXX,XX +XXX,XX @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
60 | */ | ||
61 | if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) { | ||
62 | dev_info(&hdev->pdev->dev, "IMP reset interrupt\n"); | ||
63 | - set_bit(HNAE3_IMP_RESET, &hdev->reset_pending); | ||
64 | + hclge_set_reset_pending(hdev, HNAE3_IMP_RESET); | ||
65 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
66 | *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); | ||
67 | hdev->rst_stats.imp_rst_cnt++; | ||
68 | @@ -XXX,XX +XXX,XX @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
69 | if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) { | ||
70 | dev_info(&hdev->pdev->dev, "global reset interrupt\n"); | ||
71 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
72 | - set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending); | ||
73 | + hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET); | ||
74 | *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); | ||
75 | hdev->rst_stats.global_rst_cnt++; | ||
76 | return HCLGE_VECTOR0_EVENT_RST; | ||
77 | @@ -XXX,XX +XXX,XX @@ static void hclge_do_reset(struct hclge_dev *hdev) | ||
78 | case HNAE3_FUNC_RESET: | ||
79 | dev_info(&pdev->dev, "PF reset requested\n"); | ||
80 | /* schedule again to check later */ | ||
81 | - set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); | ||
82 | + hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET); | ||
83 | hclge_reset_task_schedule(hdev); | ||
84 | break; | ||
85 | default: | ||
86 | @@ -XXX,XX +XXX,XX @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev, | ||
87 | clear_bit(HNAE3_FLR_RESET, addr); | ||
88 | } | ||
89 | |||
90 | + clear_bit(HNAE3_NONE_RESET, addr); | ||
91 | + | ||
92 | if (hdev->reset_type != HNAE3_NONE_RESET && | ||
93 | rst_level < hdev->reset_type) | ||
94 | return HNAE3_NONE_RESET; | ||
95 | @@ -XXX,XX +XXX,XX @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) | ||
96 | return false; | ||
97 | } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { | ||
98 | hdev->rst_stats.reset_fail_cnt++; | ||
99 | - set_bit(hdev->reset_type, &hdev->reset_pending); | ||
100 | + hclge_set_reset_pending(hdev, hdev->reset_type); | ||
101 | dev_info(&hdev->pdev->dev, | ||
102 | "re-schedule reset task(%u)\n", | ||
103 | hdev->rst_stats.reset_fail_cnt); | ||
104 | @@ -XXX,XX +XXX,XX @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) | ||
105 | static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | ||
106 | enum hnae3_reset_type rst_type) | ||
107 | { | ||
108 | +#define HCLGE_SUPPORT_RESET_TYPE \ | ||
109 | + (BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \ | ||
110 | + BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET)) | ||
111 | + | ||
112 | struct hclge_dev *hdev = ae_dev->priv; | ||
113 | |||
114 | + if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) { | ||
115 | + /* To prevent reset triggered by hclge_reset_event */ | ||
116 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | ||
117 | + dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n", | ||
118 | + rst_type); | ||
119 | + return; | ||
120 | + } | ||
121 | + | ||
122 | set_bit(rst_type, &hdev->default_reset_request); | ||
123 | } | ||
124 | |||
125 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
128 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | +static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev, | ||
134 | + enum hnae3_reset_type reset_type) | ||
135 | +{ | ||
136 | + /* When an incorrect reset type is executed, the get_reset_level | ||
137 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | ||
138 | + * type do not need to pending. | ||
139 | + */ | ||
140 | + if (reset_type != HNAE3_NONE_RESET) | ||
141 | + set_bit(reset_type, &hdev->reset_pending); | ||
142 | +} | ||
143 | + | ||
144 | static int hclgevf_reset_wait(struct hclgevf_dev *hdev) | ||
145 | { | ||
146 | #define HCLGEVF_RESET_WAIT_US 20000 | ||
147 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) | ||
148 | hdev->rst_stats.rst_fail_cnt); | ||
149 | |||
150 | if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) | ||
151 | - set_bit(hdev->reset_type, &hdev->reset_pending); | ||
152 | + hclgevf_set_reset_pending(hdev, hdev->reset_type); | ||
153 | |||
154 | if (hclgevf_is_reset_pending(hdev)) { | ||
155 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
156 | @@ -XXX,XX +XXX,XX @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr) | ||
157 | clear_bit(HNAE3_FLR_RESET, addr); | ||
158 | } | ||
159 | |||
160 | + clear_bit(HNAE3_NONE_RESET, addr); | ||
161 | + | ||
162 | return rst_level; | ||
163 | } | ||
164 | |||
165 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_event(struct pci_dev *pdev, | ||
166 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); | ||
167 | struct hclgevf_dev *hdev = ae_dev->priv; | ||
168 | |||
169 | - dev_info(&hdev->pdev->dev, "received reset request from VF enet\n"); | ||
170 | - | ||
171 | if (hdev->default_reset_request) | ||
172 | hdev->reset_level = | ||
173 | hclgevf_get_reset_level(&hdev->default_reset_request); | ||
174 | else | ||
175 | hdev->reset_level = HNAE3_VF_FUNC_RESET; | ||
176 | |||
177 | + dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n", | ||
178 | + hdev->reset_level); | ||
179 | + | ||
180 | /* reset of this VF requested */ | ||
181 | set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); | ||
182 | hclgevf_reset_task_schedule(hdev); | ||
183 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_event(struct pci_dev *pdev, | ||
184 | static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | ||
185 | enum hnae3_reset_type rst_type) | ||
186 | { | ||
187 | +#define HCLGEVF_SUPPORT_RESET_TYPE \ | ||
188 | + (BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \ | ||
189 | + BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \ | ||
190 | + BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET)) | ||
191 | + | ||
192 | struct hclgevf_dev *hdev = ae_dev->priv; | ||
193 | |||
194 | + if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) { | ||
195 | + /* To prevent reset triggered by hclge_reset_event */ | ||
196 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | ||
197 | + dev_info(&hdev->pdev->dev, "unsupported reset type %d\n", | ||
198 | + rst_type); | ||
199 | + return; | ||
200 | + } | ||
201 | set_bit(rst_type, &hdev->default_reset_request); | ||
202 | } | ||
203 | |||
204 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) | ||
205 | */ | ||
206 | if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { | ||
207 | /* prepare for full reset of stack + pcie interface */ | ||
208 | - set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending); | ||
209 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET); | ||
210 | |||
211 | /* "defer" schedule the reset task again */ | ||
212 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
213 | } else { | ||
214 | hdev->reset_attempts++; | ||
215 | |||
216 | - set_bit(hdev->reset_level, &hdev->reset_pending); | ||
217 | + hclgevf_set_reset_pending(hdev, hdev->reset_level); | ||
218 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
219 | } | ||
220 | hclgevf_reset_task_schedule(hdev); | ||
221 | @@ -XXX,XX +XXX,XX @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, | ||
222 | rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); | ||
223 | dev_info(&hdev->pdev->dev, | ||
224 | "receive reset interrupt 0x%x!\n", rst_ing_reg); | ||
225 | - set_bit(HNAE3_VF_RESET, &hdev->reset_pending); | ||
226 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET); | ||
227 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
228 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
229 | *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B); | ||
230 | -- | ||
231 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Hao Lan <lanhao@huawei.com> | ||
1 | 2 | ||
3 | Currently, the netdev->features is configured in hns3_nic_set_features. | ||
4 | As a result, __netdev_update_features considers that there is no feature | ||
5 | difference, and the procedures of the real features are missing. | ||
6 | |||
7 | Fixes: 2a7556bb2b73 ("net: hns3: implement ndo_features_check ops for hns3 driver") | ||
8 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
9 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
10 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
11 | Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> | ||
12 | --- | ||
13 | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 1 - | ||
14 | 1 file changed, 1 deletion(-) | ||
15 | |||
16 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
19 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static int hns3_nic_set_features(struct net_device *netdev, | ||
21 | return ret; | ||
22 | } | ||
23 | |||
24 | - netdev->features = features; | ||
25 | return 0; | ||
26 | } | ||
27 | |||
28 | -- | ||
29 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Hao Lan <lanhao@huawei.com> | |
2 | |||
3 | This patch modifies the implementation of debugfs: | ||
4 | |||
5 | When the user process stops unexpectedly, not all data of the file system | ||
6 | is read. In this case, the save_buf pointer is not released. When the | ||
7 | user process is called next time, save_buf is used to copy the cached | ||
8 | data to the user space. As a result, the queried data is stale. | ||
9 | |||
10 | To solve this problem, this patch implements .open() and .release() handler | ||
11 | for debugfs file_operations. moving allocation buffer and execution | ||
12 | of the cmd to the .open() handler and freeing in to the .release() handler. | ||
13 | Allocate separate buffer for each reader and associate the buffer | ||
14 | with the file pointer. | ||
15 | When different user read processes no longer share the buffer, | ||
16 | the stale data problem is fixed. | ||
17 | |||
18 | Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process") | ||
19 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
20 | Signed-off-by: Guangwei Zhang <zhangwangwei6@huawei.com> | ||
21 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
22 | Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> | ||
23 | --- | ||
24 | ChangeLog: | ||
25 | v1 -> v2: | ||
26 | - Fix a data inconsistency issue caused by simultaneous access of multiple readers, | ||
27 | suggested by Jakub. | ||
28 | v1: https://lore.kernel.org/all/20241107133023.3813095-1-shaojijie@huawei.com/ | ||
29 | --- | ||
30 | drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 - | ||
31 | .../ethernet/hisilicon/hns3/hns3_debugfs.c | 96 ++++++------------- | ||
32 | 2 files changed, 31 insertions(+), 68 deletions(-) | ||
33 | |||
34 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h | ||
37 | +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h | ||
38 | @@ -XXX,XX +XXX,XX @@ struct hnae3_handle { | ||
39 | |||
40 | u8 netdev_flags; | ||
41 | struct dentry *hnae3_dbgfs; | ||
42 | - /* protects concurrent contention between debugfs commands */ | ||
43 | - struct mutex dbgfs_lock; | ||
44 | - char **dbgfs_buf; | ||
45 | |||
46 | /* Network interface message level enabled bits */ | ||
47 | u32 msg_enable; | ||
48 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
51 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
52 | @@ -XXX,XX +XXX,XX @@ static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data, | ||
53 | static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, | ||
54 | size_t count, loff_t *ppos) | ||
55 | { | ||
56 | - struct hns3_dbg_data *dbg_data = filp->private_data; | ||
57 | + char *buf = filp->private_data; | ||
58 | + | ||
59 | + return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); | ||
60 | +} | ||
61 | + | ||
62 | +static int hns3_dbg_open(struct inode *inode, struct file *filp) | ||
63 | +{ | ||
64 | + struct hns3_dbg_data *dbg_data = inode->i_private; | ||
65 | struct hnae3_handle *handle = dbg_data->handle; | ||
66 | struct hns3_nic_priv *priv = handle->priv; | ||
67 | - ssize_t size = 0; | ||
68 | - char **save_buf; | ||
69 | - char *read_buf; | ||
70 | u32 index; | ||
71 | + char *buf; | ||
72 | int ret; | ||
73 | |||
74 | + if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || | ||
75 | + test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) | ||
76 | + return -EBUSY; | ||
77 | + | ||
78 | ret = hns3_dbg_get_cmd_index(dbg_data, &index); | ||
79 | if (ret) | ||
80 | return ret; | ||
81 | |||
82 | - mutex_lock(&handle->dbgfs_lock); | ||
83 | - save_buf = &handle->dbgfs_buf[index]; | ||
84 | - | ||
85 | - if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || | ||
86 | - test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { | ||
87 | - ret = -EBUSY; | ||
88 | - goto out; | ||
89 | - } | ||
90 | - | ||
91 | - if (*save_buf) { | ||
92 | - read_buf = *save_buf; | ||
93 | - } else { | ||
94 | - read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); | ||
95 | - if (!read_buf) { | ||
96 | - ret = -ENOMEM; | ||
97 | - goto out; | ||
98 | - } | ||
99 | - | ||
100 | - /* save the buffer addr until the last read operation */ | ||
101 | - *save_buf = read_buf; | ||
102 | - | ||
103 | - /* get data ready for the first time to read */ | ||
104 | - ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, | ||
105 | - read_buf, hns3_dbg_cmd[index].buf_len); | ||
106 | - if (ret) | ||
107 | - goto out; | ||
108 | - } | ||
109 | + buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL); | ||
110 | + if (!buf) | ||
111 | + return -ENOMEM; | ||
112 | |||
113 | - size = simple_read_from_buffer(buffer, count, ppos, read_buf, | ||
114 | - strlen(read_buf)); | ||
115 | - if (size > 0) { | ||
116 | - mutex_unlock(&handle->dbgfs_lock); | ||
117 | - return size; | ||
118 | + ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, | ||
119 | + buf, hns3_dbg_cmd[index].buf_len); | ||
120 | + if (ret) { | ||
121 | + kvfree(buf); | ||
122 | + return ret; | ||
123 | } | ||
124 | |||
125 | -out: | ||
126 | - /* free the buffer for the last read operation */ | ||
127 | - if (*save_buf) { | ||
128 | - kvfree(*save_buf); | ||
129 | - *save_buf = NULL; | ||
130 | - } | ||
131 | + filp->private_data = buf; | ||
132 | + return 0; | ||
133 | +} | ||
134 | |||
135 | - mutex_unlock(&handle->dbgfs_lock); | ||
136 | - return ret; | ||
137 | +static int hns3_dbg_release(struct inode *inode, struct file *filp) | ||
138 | +{ | ||
139 | + kvfree(filp->private_data); | ||
140 | + filp->private_data = NULL; | ||
141 | + return 0; | ||
142 | } | ||
143 | |||
144 | static const struct file_operations hns3_dbg_fops = { | ||
145 | .owner = THIS_MODULE, | ||
146 | - .open = simple_open, | ||
147 | + .open = hns3_dbg_open, | ||
148 | .read = hns3_dbg_read, | ||
149 | + .release = hns3_dbg_release, | ||
150 | }; | ||
151 | |||
152 | static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd) | ||
153 | @@ -XXX,XX +XXX,XX @@ int hns3_dbg_init(struct hnae3_handle *handle) | ||
154 | int ret; | ||
155 | u32 i; | ||
156 | |||
157 | - handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev, | ||
158 | - ARRAY_SIZE(hns3_dbg_cmd), | ||
159 | - sizeof(*handle->dbgfs_buf), | ||
160 | - GFP_KERNEL); | ||
161 | - if (!handle->dbgfs_buf) | ||
162 | - return -ENOMEM; | ||
163 | - | ||
164 | hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = | ||
165 | debugfs_create_dir(name, hns3_dbgfs_root); | ||
166 | handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; | ||
167 | @@ -XXX,XX +XXX,XX @@ int hns3_dbg_init(struct hnae3_handle *handle) | ||
168 | debugfs_create_dir(hns3_dbg_dentry[i].name, | ||
169 | handle->hnae3_dbgfs); | ||
170 | |||
171 | - mutex_init(&handle->dbgfs_lock); | ||
172 | - | ||
173 | for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) { | ||
174 | if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES && | ||
175 | ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) || | ||
176 | @@ -XXX,XX +XXX,XX @@ int hns3_dbg_init(struct hnae3_handle *handle) | ||
177 | out: | ||
178 | debugfs_remove_recursive(handle->hnae3_dbgfs); | ||
179 | handle->hnae3_dbgfs = NULL; | ||
180 | - mutex_destroy(&handle->dbgfs_lock); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | void hns3_dbg_uninit(struct hnae3_handle *handle) | ||
185 | { | ||
186 | - u32 i; | ||
187 | - | ||
188 | debugfs_remove_recursive(handle->hnae3_dbgfs); | ||
189 | handle->hnae3_dbgfs = NULL; | ||
190 | - | ||
191 | - for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) | ||
192 | - if (handle->dbgfs_buf[i]) { | ||
193 | - kvfree(handle->dbgfs_buf[i]); | ||
194 | - handle->dbgfs_buf[i] = NULL; | ||
195 | - } | ||
196 | - | ||
197 | - mutex_destroy(&handle->dbgfs_lock); | ||
198 | } | ||
199 | |||
200 | void hns3_dbg_register_debugfs(const char *debugfs_dir_name) | ||
201 | -- | ||
202 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Yonglong Liu <liuyonglong@huawei.com> | 1 | From: Jian Shen <shenjian15@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | In hclge_add_fd_entry(), if the flow type is FLOW_EXT, and the data of | 3 | Currently, there is a time window between misc irq enabled |
4 | m_ext is all zero, then some members of the local variable "info" are | 4 | and service task inited. If an interrupte is reported at |
5 | not initialized. | 5 | this time, it will cause warning like below: |
6 | 6 | ||
7 | Fixes: 67b0e1428e2f ("net: hns3: add support for user-def data of flow director") | 7 | [ 16.324639] Call trace: |
8 | Signed-off-by: Yonglong Liu <liuyonglong@huawei.com> | 8 | [ 16.324641] __queue_delayed_work+0xb8/0xe0 |
9 | [ 16.324643] mod_delayed_work_on+0x78/0xd0 | ||
10 | [ 16.324655] hclge_errhand_task_schedule+0x58/0x90 [hclge] | ||
11 | [ 16.324662] hclge_misc_irq_handle+0x168/0x240 [hclge] | ||
12 | [ 16.324666] __handle_irq_event_percpu+0x64/0x1e0 | ||
13 | [ 16.324667] handle_irq_event+0x80/0x170 | ||
14 | [ 16.324670] handle_fasteoi_edge_irq+0x110/0x2bc | ||
15 | [ 16.324671] __handle_domain_irq+0x84/0xfc | ||
16 | [ 16.324673] gic_handle_irq+0x88/0x2c0 | ||
17 | [ 16.324674] el1_irq+0xb8/0x140 | ||
18 | [ 16.324677] arch_cpu_idle+0x18/0x40 | ||
19 | [ 16.324679] default_idle_call+0x5c/0x1bc | ||
20 | [ 16.324682] cpuidle_idle_call+0x18c/0x1c4 | ||
21 | [ 16.324684] do_idle+0x174/0x17c | ||
22 | [ 16.324685] cpu_startup_entry+0x30/0x6c | ||
23 | [ 16.324687] secondary_start_kernel+0x1a4/0x280 | ||
24 | [ 16.324688] ---[ end trace 6aa0bff672a964aa ]--- | ||
25 | |||
26 | So don't auto enable misc vector when request irq.. | ||
27 | |||
28 | Fixes: 7be1b9f3e99f ("net: hns3: make hclge_service use delayed workqueue") | ||
29 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 30 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
10 | --- | 31 | --- |
11 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 32 | .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 12 +++++++----- |
12 | 1 file changed, 1 insertion(+), 1 deletion(-) | 33 | 1 file changed, 7 insertions(+), 5 deletions(-) |
13 | 34 | ||
14 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 35 | 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 | 36 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 37 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
17 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 38 | +++ 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, | 39 | @@ -XXX,XX +XXX,XX @@ |
19 | struct ethtool_rxnfc *cmd) | 40 | #include <linux/etherdevice.h> |
20 | { | 41 | #include <linux/init.h> |
21 | struct hclge_vport *vport = hclge_get_vport(handle); | 42 | #include <linux/interrupt.h> |
22 | + struct hclge_fd_user_def_info info = {0}; | 43 | +#include <linux/irq.h> |
23 | struct hclge_dev *hdev = vport->back; | 44 | #include <linux/kernel.h> |
24 | - struct hclge_fd_user_def_info info; | 45 | #include <linux/module.h> |
25 | u16 dst_vport_id = 0, q_index = 0; | 46 | #include <linux/netdevice.h> |
26 | struct ethtool_rx_flow_spec *fs; | 47 | @@ -XXX,XX +XXX,XX @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) |
27 | struct hclge_fd_rule *rule; | 48 | snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", |
49 | HCLGE_NAME, pci_name(hdev->pdev)); | ||
50 | ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, | ||
51 | - 0, hdev->misc_vector.name, hdev); | ||
52 | + IRQF_NO_AUTOEN, hdev->misc_vector.name, hdev); | ||
53 | if (ret) { | ||
54 | hclge_free_vector(hdev, 0); | ||
55 | dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", | ||
56 | @@ -XXX,XX +XXX,XX @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
57 | |||
58 | hclge_init_rxd_adv_layout(hdev); | ||
59 | |||
60 | - /* Enable MISC vector(vector0) */ | ||
61 | - hclge_enable_vector(&hdev->misc_vector, true); | ||
62 | - | ||
63 | ret = hclge_init_wol(hdev); | ||
64 | if (ret) | ||
65 | dev_warn(&pdev->dev, | ||
66 | @@ -XXX,XX +XXX,XX @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
67 | hclge_state_init(hdev); | ||
68 | hdev->last_reset_time = jiffies; | ||
69 | |||
70 | + /* Enable MISC vector(vector0) */ | ||
71 | + enable_irq(hdev->misc_vector.vector_irq); | ||
72 | + hclge_enable_vector(&hdev->misc_vector, true); | ||
73 | + | ||
74 | dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", | ||
75 | HCLGE_DRIVER_NAME); | ||
76 | |||
77 | @@ -XXX,XX +XXX,XX @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
78 | |||
79 | /* Disable MISC vector(vector0) */ | ||
80 | hclge_enable_vector(&hdev->misc_vector, false); | ||
81 | - synchronize_irq(hdev->misc_vector.vector_irq); | ||
82 | + disable_irq(hdev->misc_vector.vector_irq); | ||
83 | |||
84 | /* Disable all hw interrupts */ | ||
85 | hclge_config_mac_tnl_int(hdev, false); | ||
28 | -- | 86 | -- |
29 | 2.33.0 | 87 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Jian Shen <shenjian15@huawei.com> | 1 | From: Jian Shen <shenjian15@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | The VF driver missed to store the rx VLAN tag strip state when | 3 | Currently the misc irq is initialized before reset_timer setup. But |
4 | user change the rx VLAN tag offload state. And it will default | 4 | it will access the reset_timer in the irq handler. So initialize |
5 | to enable the rx vlan tag strip when re-init VF device after | 5 | the reset_timer earlier. |
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 | 6 | ||
11 | Fixes: b2641e2ad456 ("net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver") | 7 | Fixes: ff200099d271 ("net: hns3: remove unnecessary work in hclgevf_main") |
12 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | 8 | Signed-off-by: Jian Shen <shenjian15@huawei.com> |
13 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
14 | --- | 10 | --- |
15 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++++----- | 11 | ChangeLog: |
16 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | 12 | v2 RESEND -> v3: |
17 | 2 files changed, 21 insertions(+), 7 deletions(-) | 13 | - Add one comment, suggested by Michal Swiatkowski. |
14 | v2 RESEND: https://lore.kernel.org/all/20241217010839.1742227-1-shaojijie@huawei.com/ | ||
15 | --- | ||
16 | drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 3 ++- | ||
17 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
18 | 18 | ||
19 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 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 | 20 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 21 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |
22 | +++ b/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) | 23 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) |
24 | rtnl_unlock(); | 24 | clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); |
25 | } | 25 | |
26 | 26 | INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); | |
27 | -static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | 27 | + /* timer needs to be initialized before misc irq */ |
28 | +static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable) | 28 | + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); |
29 | { | 29 | |
30 | - struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 30 | mutex_init(&hdev->mbx_resp.mbx_mutex); |
31 | struct hclge_vf_to_pf_msg send_msg; | 31 | sema_init(&hdev->reset_sem, 1); |
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) | 32 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) |
80 | goto err_config; | 33 | HCLGEVF_DRIVER_NAME); |
81 | } | 34 | |
82 | 35 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); | |
83 | - ret = hclgevf_init_vlan_config(hdev); | 36 | - timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); |
84 | + ret = hclgevf_init_vlan_config(hdev, true); | 37 | |
85 | if (ret) { | 38 | return 0; |
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 | 39 | ||
102 | -- | 40 | -- |
103 | 2.33.0 | 41 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Hao Lan <lanhao@huawei.com> | 1 | From: Hao Lan <lanhao@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | There are spelling mistakes in hclgevf_get_regs. Fix them. | 3 | The TQP BAR space is divided into two segments. TQPs 0-1023 and TQPs |
4 | 1024-1279 are in different BAR space addresses. However, | ||
5 | hclge_fetch_pf_reg does not distinguish the tqp space information when | ||
6 | reading the tqp space information. When the number of TQPs is greater | ||
7 | than 1024, access bar space overwriting occurs. | ||
8 | The problem of different segments has been considered during the | ||
9 | initialization of tqp.io_base. Therefore, tqp.io_base is directly used | ||
10 | when the queue is read in hclge_fetch_pf_reg. | ||
4 | 11 | ||
12 | The error message: | ||
13 | |||
14 | Unable to handle kernel paging request at virtual address ffff800037200000 | ||
15 | pc : hclge_fetch_pf_reg+0x138/0x250 [hclge] | ||
16 | lr : hclge_get_regs+0x84/0x1d0 [hclge] | ||
17 | Call trace: | ||
18 | hclge_fetch_pf_reg+0x138/0x250 [hclge] | ||
19 | hclge_get_regs+0x84/0x1d0 [hclge] | ||
20 | hns3_get_regs+0x2c/0x50 [hns3] | ||
21 | ethtool_get_regs+0xf4/0x270 | ||
22 | dev_ethtool+0x674/0x8a0 | ||
23 | dev_ioctl+0x270/0x36c | ||
24 | sock_do_ioctl+0x110/0x2a0 | ||
25 | sock_ioctl+0x2ac/0x530 | ||
26 | __arm64_sys_ioctl+0xa8/0x100 | ||
27 | invoke_syscall+0x4c/0x124 | ||
28 | el0_svc_common.constprop.0+0x140/0x15c | ||
29 | do_el0_svc+0x30/0xd0 | ||
30 | el0_svc+0x1c/0x2c | ||
31 | el0_sync_handler+0xb0/0xb4 | ||
32 | el0_sync+0x168/0x180 | ||
33 | |||
34 | Fixes: 939ccd107ffc ("net: hns3: move dump regs function to a separate file") | ||
5 | Signed-off-by: Hao Lan <lanhao@huawei.com> | 35 | Signed-off-by: Hao Lan <lanhao@huawei.com> |
6 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 36 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
7 | --- | 37 | --- |
8 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 38 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | 9 +++++---- |
9 | 1 file changed, 14 insertions(+), 13 deletions(-) | 39 | .../net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 9 +++++---- |
40 | 2 files changed, 10 insertions(+), 8 deletions(-) | ||
10 | 41 | ||
42 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
45 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
46 | @@ -XXX,XX +XXX,XX @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) | ||
47 | static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, | ||
48 | struct hnae3_knic_private_info *kinfo) | ||
49 | { | ||
50 | -#define HCLGE_RING_REG_OFFSET 0x200 | ||
51 | #define HCLGE_RING_INT_REG_OFFSET 0x4 | ||
52 | |||
53 | + struct hnae3_queue *tqp; | ||
54 | int i, j, reg_num; | ||
55 | int data_num_sum; | ||
56 | u32 *reg = data; | ||
57 | @@ -XXX,XX +XXX,XX @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, | ||
58 | reg_num = ARRAY_SIZE(ring_reg_addr_list); | ||
59 | for (j = 0; j < kinfo->num_tqps; j++) { | ||
60 | reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); | ||
61 | + tqp = kinfo->tqp[j]; | ||
62 | for (i = 0; i < reg_num; i++) | ||
63 | - *reg++ = hclge_read_dev(&hdev->hw, | ||
64 | - ring_reg_addr_list[i] + | ||
65 | - HCLGE_RING_REG_OFFSET * j); | ||
66 | + *reg++ = readl_relaxed(tqp->io_base - | ||
67 | + HCLGE_TQP_REG_OFFSET + | ||
68 | + ring_reg_addr_list[i]); | ||
69 | } | ||
70 | data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; | ||
71 | |||
11 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 72 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
12 | index XXXXXXX..XXXXXXX 100644 | 73 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 74 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
14 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 75 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
76 | @@ -XXX,XX +XXX,XX @@ int hclgevf_get_regs_len(struct hnae3_handle *handle) | ||
77 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | ||
78 | void *data) | ||
79 | { | ||
80 | -#define HCLGEVF_RING_REG_OFFSET 0x200 | ||
81 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 | ||
82 | |||
83 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
84 | + struct hnae3_queue *tqp; | ||
85 | int i, j, reg_um; | ||
86 | u32 *reg = data; | ||
87 | |||
15 | @@ -XXX,XX +XXX,XX @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | 88 | @@ -XXX,XX +XXX,XX @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, |
16 | 89 | reg_um = ARRAY_SIZE(ring_reg_addr_list); | |
17 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
18 | struct hnae3_queue *tqp; | ||
19 | - int i, j, reg_um; | ||
20 | + int i, j, reg_num; | ||
21 | u32 *reg = data; | ||
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++) { | 90 | for (j = 0; j < hdev->num_tqps; j++) { |
46 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); | 91 | 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); | 92 | + tqp = &hdev->htqp[j].q; |
48 | tqp = &hdev->htqp[j].q; | 93 | for (i = 0; i < reg_um; i++) |
49 | - for (i = 0; i < reg_um; i++) | 94 | - *reg++ = hclgevf_read_dev(&hdev->hw, |
50 | + for (i = 0; i < reg_num; i++) | 95 | - ring_reg_addr_list[i] + |
51 | *reg++ = readl_relaxed(tqp->io_base - | 96 | - HCLGEVF_RING_REG_OFFSET * j); |
52 | HCLGEVF_TQP_REG_OFFSET + | 97 | + *reg++ = readl_relaxed(tqp->io_base - |
53 | ring_reg_addr_list[i]); | 98 | + HCLGEVF_TQP_REG_OFFSET + |
99 | + ring_reg_addr_list[i]); | ||
54 | } | 100 | } |
55 | 101 | ||
56 | - reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); | 102 | reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); |
57 | + reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); | ||
58 | for (j = 0; j < hdev->num_msi_used - 1; j++) { | ||
59 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg); | ||
60 | - for (i = 0; i < reg_um; i++) | ||
61 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, | ||
62 | + reg_num, reg); | ||
63 | + for (i = 0; i < reg_num; i++) | ||
64 | *reg++ = hclgevf_read_dev(&hdev->hw, | ||
65 | tqp_intr_reg_addr_list[i] + | ||
66 | HCLGEVF_RING_INT_REG_OFFSET * j); | ||
67 | -- | 103 | -- |
68 | 2.33.0 | 104 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jie Wang <wangjie125@huawei.com> | ||
1 | 2 | ||
3 | Currently, HIP08 devices does not register the ptp devices, so the | ||
4 | hdev->ptp is NULL. But the tx process would still try to set hardware time | ||
5 | stamp info with SKBTX_HW_TSTAMP flag and cause a kernel crash. | ||
6 | |||
7 | [ 128.087798] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018 | ||
8 | ... | ||
9 | [ 128.280251] pc : hclge_ptp_set_tx_info+0x2c/0x140 [hclge] | ||
10 | [ 128.286600] lr : hclge_ptp_set_tx_info+0x20/0x140 [hclge] | ||
11 | [ 128.292938] sp : ffff800059b93140 | ||
12 | [ 128.297200] x29: ffff800059b93140 x28: 0000000000003280 | ||
13 | [ 128.303455] x27: ffff800020d48280 x26: ffff0cb9dc814080 | ||
14 | [ 128.309715] x25: ffff0cb9cde93fa0 x24: 0000000000000001 | ||
15 | [ 128.315969] x23: 0000000000000000 x22: 0000000000000194 | ||
16 | [ 128.322219] x21: ffff0cd94f986000 x20: 0000000000000000 | ||
17 | [ 128.328462] x19: ffff0cb9d2a166c0 x18: 0000000000000000 | ||
18 | [ 128.334698] x17: 0000000000000000 x16: ffffcf1fc523ed24 | ||
19 | [ 128.340934] x15: 0000ffffd530a518 x14: 0000000000000000 | ||
20 | [ 128.347162] x13: ffff0cd6bdb31310 x12: 0000000000000368 | ||
21 | [ 128.353388] x11: ffff0cb9cfbc7070 x10: ffff2cf55dd11e02 | ||
22 | [ 128.359606] x9 : ffffcf1f85a212b4 x8 : ffff0cd7cf27dab0 | ||
23 | [ 128.365831] x7 : 0000000000000a20 x6 : ffff0cd7cf27d000 | ||
24 | [ 128.372040] x5 : 0000000000000000 x4 : 000000000000ffff | ||
25 | [ 128.378243] x3 : 0000000000000400 x2 : ffffcf1f85a21294 | ||
26 | [ 128.384437] x1 : ffff0cb9db520080 x0 : ffff0cb9db500080 | ||
27 | [ 128.390626] Call trace: | ||
28 | [ 128.393964] hclge_ptp_set_tx_info+0x2c/0x140 [hclge] | ||
29 | [ 128.399893] hns3_nic_net_xmit+0x39c/0x4c4 [hns3] | ||
30 | [ 128.405468] xmit_one.constprop.0+0xc4/0x200 | ||
31 | [ 128.410600] dev_hard_start_xmit+0x54/0xf0 | ||
32 | [ 128.415556] sch_direct_xmit+0xe8/0x634 | ||
33 | [ 128.420246] __dev_queue_xmit+0x224/0xc70 | ||
34 | [ 128.425101] dev_queue_xmit+0x1c/0x40 | ||
35 | [ 128.429608] ovs_vport_send+0xac/0x1a0 [openvswitch] | ||
36 | [ 128.435409] do_output+0x60/0x17c [openvswitch] | ||
37 | [ 128.440770] do_execute_actions+0x898/0x8c4 [openvswitch] | ||
38 | [ 128.446993] ovs_execute_actions+0x64/0xf0 [openvswitch] | ||
39 | [ 128.453129] ovs_dp_process_packet+0xa0/0x224 [openvswitch] | ||
40 | [ 128.459530] ovs_vport_receive+0x7c/0xfc [openvswitch] | ||
41 | [ 128.465497] internal_dev_xmit+0x34/0xb0 [openvswitch] | ||
42 | [ 128.471460] xmit_one.constprop.0+0xc4/0x200 | ||
43 | [ 128.476561] dev_hard_start_xmit+0x54/0xf0 | ||
44 | [ 128.481489] __dev_queue_xmit+0x968/0xc70 | ||
45 | [ 128.486330] dev_queue_xmit+0x1c/0x40 | ||
46 | [ 128.490856] ip_finish_output2+0x250/0x570 | ||
47 | [ 128.495810] __ip_finish_output+0x170/0x1e0 | ||
48 | [ 128.500832] ip_finish_output+0x3c/0xf0 | ||
49 | [ 128.505504] ip_output+0xbc/0x160 | ||
50 | [ 128.509654] ip_send_skb+0x58/0xd4 | ||
51 | [ 128.513892] udp_send_skb+0x12c/0x354 | ||
52 | [ 128.518387] udp_sendmsg+0x7a8/0x9c0 | ||
53 | [ 128.522793] inet_sendmsg+0x4c/0x8c | ||
54 | [ 128.527116] __sock_sendmsg+0x48/0x80 | ||
55 | [ 128.531609] __sys_sendto+0x124/0x164 | ||
56 | [ 128.536099] __arm64_sys_sendto+0x30/0x5c | ||
57 | [ 128.540935] invoke_syscall+0x50/0x130 | ||
58 | [ 128.545508] el0_svc_common.constprop.0+0x10c/0x124 | ||
59 | [ 128.551205] do_el0_svc+0x34/0xdc | ||
60 | [ 128.555347] el0_svc+0x20/0x30 | ||
61 | [ 128.559227] el0_sync_handler+0xb8/0xc0 | ||
62 | [ 128.563883] el0_sync+0x160/0x180 | ||
63 | |||
64 | Fixes: 0bf5eb788512 ("net: hns3: add support for PTP") | ||
65 | Signed-off-by: Jie Wang <wangjie125@huawei.com> | ||
66 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
67 | Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> | ||
68 | --- | ||
69 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 3 +++ | ||
70 | 1 file changed, 3 insertions(+) | ||
71 | |||
72 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
75 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
76 | @@ -XXX,XX +XXX,XX @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb) | ||
77 | struct hclge_dev *hdev = vport->back; | ||
78 | struct hclge_ptp *ptp = hdev->ptp; | ||
79 | |||
80 | + if (!ptp) | ||
81 | + return false; | ||
82 | + | ||
83 | if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) || | ||
84 | test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) { | ||
85 | ptp->tx_skipped++; | ||
86 | -- | ||
87 | 2.33.0 | diff view generated by jsdifflib |