|
30 | 30 | * SOFTWARE.
|
31 | 31 | */
|
32 | 32 |
|
33 |
| -#include <linux/io.h> |
34 | 33 | #include <rdma/ib_umem_odp.h>
|
35 | 34 | #include "mlx5_ib.h"
|
36 |
| -#include <linux/jiffies.h> |
37 | 35 |
|
38 | 36 | /*
|
39 | 37 | * Fill in a physical address list. ib_umem_num_dma_blocks() entries will be
|
@@ -95,199 +93,3 @@ unsigned long __mlx5_umem_find_best_quantized_pgoff(
|
95 | 93 | return 0;
|
96 | 94 | return page_size;
|
97 | 95 | }
|
98 |
| - |
99 |
| -#define WR_ID_BF 0xBF |
100 |
| -#define WR_ID_END 0xBAD |
101 |
| -#define TEST_WC_NUM_WQES 255 |
102 |
| -#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100) |
103 |
| -static int post_send_nop(struct mlx5_ib_dev *dev, struct ib_qp *ibqp, u64 wr_id, |
104 |
| - bool signaled) |
105 |
| -{ |
106 |
| - struct mlx5_ib_qp *qp = to_mqp(ibqp); |
107 |
| - struct mlx5_wqe_ctrl_seg *ctrl; |
108 |
| - struct mlx5_bf *bf = &qp->bf; |
109 |
| - __be32 mmio_wqe[16] = {}; |
110 |
| - unsigned long flags; |
111 |
| - unsigned int idx; |
112 |
| - |
113 |
| - if (unlikely(dev->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)) |
114 |
| - return -EIO; |
115 |
| - |
116 |
| - spin_lock_irqsave(&qp->sq.lock, flags); |
117 |
| - |
118 |
| - idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1); |
119 |
| - ctrl = mlx5_frag_buf_get_wqe(&qp->sq.fbc, idx); |
120 |
| - |
121 |
| - memset(ctrl, 0, sizeof(struct mlx5_wqe_ctrl_seg)); |
122 |
| - ctrl->fm_ce_se = signaled ? MLX5_WQE_CTRL_CQ_UPDATE : 0; |
123 |
| - ctrl->opmod_idx_opcode = |
124 |
| - cpu_to_be32(((u32)(qp->sq.cur_post) << 8) | MLX5_OPCODE_NOP); |
125 |
| - ctrl->qpn_ds = cpu_to_be32((sizeof(struct mlx5_wqe_ctrl_seg) / 16) | |
126 |
| - (qp->trans_qp.base.mqp.qpn << 8)); |
127 |
| - |
128 |
| - qp->sq.wrid[idx] = wr_id; |
129 |
| - qp->sq.w_list[idx].opcode = MLX5_OPCODE_NOP; |
130 |
| - qp->sq.wqe_head[idx] = qp->sq.head + 1; |
131 |
| - qp->sq.cur_post += DIV_ROUND_UP(sizeof(struct mlx5_wqe_ctrl_seg), |
132 |
| - MLX5_SEND_WQE_BB); |
133 |
| - qp->sq.w_list[idx].next = qp->sq.cur_post; |
134 |
| - qp->sq.head++; |
135 |
| - |
136 |
| - memcpy(mmio_wqe, ctrl, sizeof(*ctrl)); |
137 |
| - ((struct mlx5_wqe_ctrl_seg *)&mmio_wqe)->fm_ce_se |= |
138 |
| - MLX5_WQE_CTRL_CQ_UPDATE; |
139 |
| - |
140 |
| - /* Make sure that descriptors are written before |
141 |
| - * updating doorbell record and ringing the doorbell |
142 |
| - */ |
143 |
| - wmb(); |
144 |
| - |
145 |
| - qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post); |
146 |
| - |
147 |
| - /* Make sure doorbell record is visible to the HCA before |
148 |
| - * we hit doorbell |
149 |
| - */ |
150 |
| - wmb(); |
151 |
| - __iowrite64_copy(bf->bfreg->map + bf->offset, mmio_wqe, |
152 |
| - sizeof(mmio_wqe) / 8); |
153 |
| - |
154 |
| - bf->offset ^= bf->buf_size; |
155 |
| - |
156 |
| - spin_unlock_irqrestore(&qp->sq.lock, flags); |
157 |
| - |
158 |
| - return 0; |
159 |
| -} |
160 |
| - |
161 |
| -static int test_wc_poll_cq_result(struct mlx5_ib_dev *dev, struct ib_cq *cq) |
162 |
| -{ |
163 |
| - int ret; |
164 |
| - struct ib_wc wc = {}; |
165 |
| - unsigned long end = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES; |
166 |
| - |
167 |
| - do { |
168 |
| - ret = ib_poll_cq(cq, 1, &wc); |
169 |
| - if (ret < 0 || wc.status) |
170 |
| - return ret < 0 ? ret : -EINVAL; |
171 |
| - if (ret) |
172 |
| - break; |
173 |
| - } while (!time_after(jiffies, end)); |
174 |
| - |
175 |
| - if (!ret) |
176 |
| - return -ETIMEDOUT; |
177 |
| - |
178 |
| - if (wc.wr_id != WR_ID_BF) |
179 |
| - ret = 0; |
180 |
| - |
181 |
| - return ret; |
182 |
| -} |
183 |
| - |
184 |
| -static int test_wc_do_send(struct mlx5_ib_dev *dev, struct ib_qp *qp) |
185 |
| -{ |
186 |
| - int err, i; |
187 |
| - |
188 |
| - for (i = 0; i < TEST_WC_NUM_WQES; i++) { |
189 |
| - err = post_send_nop(dev, qp, WR_ID_BF, false); |
190 |
| - if (err) |
191 |
| - return err; |
192 |
| - } |
193 |
| - |
194 |
| - return post_send_nop(dev, qp, WR_ID_END, true); |
195 |
| -} |
196 |
| - |
197 |
| -int mlx5_ib_test_wc(struct mlx5_ib_dev *dev) |
198 |
| -{ |
199 |
| - struct ib_cq_init_attr cq_attr = { .cqe = TEST_WC_NUM_WQES + 1 }; |
200 |
| - int port_type_cap = MLX5_CAP_GEN(dev->mdev, port_type); |
201 |
| - struct ib_qp_init_attr qp_init_attr = { |
202 |
| - .cap = { .max_send_wr = TEST_WC_NUM_WQES }, |
203 |
| - .qp_type = IB_QPT_UD, |
204 |
| - .sq_sig_type = IB_SIGNAL_REQ_WR, |
205 |
| - .create_flags = MLX5_IB_QP_CREATE_WC_TEST, |
206 |
| - }; |
207 |
| - struct ib_qp_attr qp_attr = { .port_num = 1 }; |
208 |
| - struct ib_device *ibdev = &dev->ib_dev; |
209 |
| - struct ib_qp *qp; |
210 |
| - struct ib_cq *cq; |
211 |
| - struct ib_pd *pd; |
212 |
| - int ret; |
213 |
| - |
214 |
| - if (!MLX5_CAP_GEN(dev->mdev, bf)) |
215 |
| - return 0; |
216 |
| - |
217 |
| - if (!dev->mdev->roce.roce_en && |
218 |
| - port_type_cap == MLX5_CAP_PORT_TYPE_ETH) { |
219 |
| - if (mlx5_core_is_pf(dev->mdev)) |
220 |
| - dev->wc_support = arch_can_pci_mmap_wc(); |
221 |
| - return 0; |
222 |
| - } |
223 |
| - |
224 |
| - ret = mlx5_alloc_bfreg(dev->mdev, &dev->wc_bfreg, true, false); |
225 |
| - if (ret) |
226 |
| - goto print_err; |
227 |
| - |
228 |
| - if (!dev->wc_bfreg.wc) |
229 |
| - goto out1; |
230 |
| - |
231 |
| - pd = ib_alloc_pd(ibdev, 0); |
232 |
| - if (IS_ERR(pd)) { |
233 |
| - ret = PTR_ERR(pd); |
234 |
| - goto out1; |
235 |
| - } |
236 |
| - |
237 |
| - cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr); |
238 |
| - if (IS_ERR(cq)) { |
239 |
| - ret = PTR_ERR(cq); |
240 |
| - goto out2; |
241 |
| - } |
242 |
| - |
243 |
| - qp_init_attr.recv_cq = cq; |
244 |
| - qp_init_attr.send_cq = cq; |
245 |
| - qp = ib_create_qp(pd, &qp_init_attr); |
246 |
| - if (IS_ERR(qp)) { |
247 |
| - ret = PTR_ERR(qp); |
248 |
| - goto out3; |
249 |
| - } |
250 |
| - |
251 |
| - qp_attr.qp_state = IB_QPS_INIT; |
252 |
| - ret = ib_modify_qp(qp, &qp_attr, |
253 |
| - IB_QP_STATE | IB_QP_PORT | IB_QP_PKEY_INDEX | |
254 |
| - IB_QP_QKEY); |
255 |
| - if (ret) |
256 |
| - goto out4; |
257 |
| - |
258 |
| - qp_attr.qp_state = IB_QPS_RTR; |
259 |
| - ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE); |
260 |
| - if (ret) |
261 |
| - goto out4; |
262 |
| - |
263 |
| - qp_attr.qp_state = IB_QPS_RTS; |
264 |
| - ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_SQ_PSN); |
265 |
| - if (ret) |
266 |
| - goto out4; |
267 |
| - |
268 |
| - ret = test_wc_do_send(dev, qp); |
269 |
| - if (ret < 0) |
270 |
| - goto out4; |
271 |
| - |
272 |
| - ret = test_wc_poll_cq_result(dev, cq); |
273 |
| - if (ret > 0) { |
274 |
| - dev->wc_support = true; |
275 |
| - ret = 0; |
276 |
| - } |
277 |
| - |
278 |
| -out4: |
279 |
| - ib_destroy_qp(qp); |
280 |
| -out3: |
281 |
| - ib_destroy_cq(cq); |
282 |
| -out2: |
283 |
| - ib_dealloc_pd(pd); |
284 |
| -out1: |
285 |
| - mlx5_free_bfreg(dev->mdev, &dev->wc_bfreg); |
286 |
| -print_err: |
287 |
| - if (ret) |
288 |
| - mlx5_ib_err( |
289 |
| - dev, |
290 |
| - "Error %d while trying to test write-combining support\n", |
291 |
| - ret); |
292 |
| - return ret; |
293 |
| -} |
0 commit comments