.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved. |
---|
3 | 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * This software is available to you under a choice of one of two |
---|
6 | | - * licenses. You may choose to be licensed under the terms of the GNU |
---|
7 | | - * General Public License (GPL) Version 2, available from the file |
---|
8 | | - * COPYING in the main directory of this source tree, or the |
---|
9 | | - * OpenIB.org BSD license below: |
---|
10 | | - * |
---|
11 | | - * Redistribution and use in source and binary forms, with or |
---|
12 | | - * without modification, are permitted provided that the following |
---|
13 | | - * conditions are met: |
---|
14 | | - * |
---|
15 | | - * - Redistributions of source code must retain the above |
---|
16 | | - * copyright notice, this list of conditions and the following |
---|
17 | | - * disclaimer. |
---|
18 | | - * |
---|
19 | | - * - Redistributions in binary form must reproduce the above |
---|
20 | | - * copyright notice, this list of conditions and the following |
---|
21 | | - * disclaimer in the documentation and/or other materials |
---|
22 | | - * provided with the distribution. |
---|
23 | | - * |
---|
24 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
25 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
---|
26 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
27 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
---|
28 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
---|
29 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
---|
30 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
31 | | - * SOFTWARE. |
---|
32 | 5 | */ |
---|
33 | 6 | |
---|
34 | 7 | #include <linux/skbuff.h> |
---|
35 | 8 | #include <linux/delay.h> |
---|
36 | 9 | #include <linux/sched.h> |
---|
37 | 10 | #include <linux/vmalloc.h> |
---|
| 11 | +#include <rdma/uverbs_ioctl.h> |
---|
38 | 12 | |
---|
39 | 13 | #include "rxe.h" |
---|
40 | 14 | #include "rxe_loc.h" |
---|
.. | .. |
---|
97 | 71 | goto err1; |
---|
98 | 72 | |
---|
99 | 73 | if (init->qp_type == IB_QPT_SMI || init->qp_type == IB_QPT_GSI) { |
---|
100 | | - if (port_num != 1) { |
---|
| 74 | + if (!rdma_is_port_valid(&rxe->ib_dev, port_num)) { |
---|
101 | 75 | pr_warn("invalid port = %d\n", port_num); |
---|
102 | 76 | goto err1; |
---|
103 | 77 | } |
---|
.. | .. |
---|
210 | 184 | spin_lock_init(&qp->grp_lock); |
---|
211 | 185 | spin_lock_init(&qp->state_lock); |
---|
212 | 186 | |
---|
| 187 | + spin_lock_init(&qp->req.task.state_lock); |
---|
| 188 | + spin_lock_init(&qp->resp.task.state_lock); |
---|
| 189 | + spin_lock_init(&qp->comp.task.state_lock); |
---|
| 190 | + |
---|
| 191 | + spin_lock_init(&qp->sq.sq_lock); |
---|
| 192 | + spin_lock_init(&qp->rq.producer_lock); |
---|
| 193 | + spin_lock_init(&qp->rq.consumer_lock); |
---|
| 194 | + |
---|
| 195 | + skb_queue_head_init(&qp->req_pkts); |
---|
| 196 | + skb_queue_head_init(&qp->resp_pkts); |
---|
| 197 | + |
---|
213 | 198 | atomic_set(&qp->ssn, 0); |
---|
214 | 199 | atomic_set(&qp->skb_out, 0); |
---|
215 | 200 | } |
---|
216 | 201 | |
---|
217 | 202 | static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, |
---|
218 | | - struct ib_qp_init_attr *init, |
---|
219 | | - struct ib_ucontext *context, |
---|
| 203 | + struct ib_qp_init_attr *init, struct ib_udata *udata, |
---|
220 | 204 | struct rxe_create_qp_resp __user *uresp) |
---|
221 | 205 | { |
---|
222 | 206 | int err; |
---|
.. | .. |
---|
227 | 211 | return err; |
---|
228 | 212 | qp->sk->sk->sk_user_data = qp; |
---|
229 | 213 | |
---|
| 214 | + /* pick a source UDP port number for this QP based on |
---|
| 215 | + * the source QPN. this spreads traffic for different QPs |
---|
| 216 | + * across different NIC RX queues (while using a single |
---|
| 217 | + * flow for a given QP to maintain packet order). |
---|
| 218 | + * the port number must be in the Dynamic Ports range |
---|
| 219 | + * (0xc000 - 0xffff). |
---|
| 220 | + */ |
---|
| 221 | + qp->src_port = RXE_ROCE_V2_SPORT + |
---|
| 222 | + (hash_32_generic(qp_num(qp), 14) & 0x3fff); |
---|
230 | 223 | qp->sq.max_wr = init->cap.max_send_wr; |
---|
231 | | - qp->sq.max_sge = init->cap.max_send_sge; |
---|
232 | | - qp->sq.max_inline = init->cap.max_inline_data; |
---|
233 | 224 | |
---|
234 | | - wqe_size = max_t(int, sizeof(struct rxe_send_wqe) + |
---|
235 | | - qp->sq.max_sge * sizeof(struct ib_sge), |
---|
236 | | - sizeof(struct rxe_send_wqe) + |
---|
237 | | - qp->sq.max_inline); |
---|
| 225 | + /* These caps are limited by rxe_qp_chk_cap() done by the caller */ |
---|
| 226 | + wqe_size = max_t(int, init->cap.max_send_sge * sizeof(struct ib_sge), |
---|
| 227 | + init->cap.max_inline_data); |
---|
| 228 | + qp->sq.max_sge = init->cap.max_send_sge = |
---|
| 229 | + wqe_size / sizeof(struct ib_sge); |
---|
| 230 | + qp->sq.max_inline = init->cap.max_inline_data = wqe_size; |
---|
| 231 | + wqe_size += sizeof(struct rxe_send_wqe); |
---|
238 | 232 | |
---|
239 | | - qp->sq.queue = rxe_queue_init(rxe, |
---|
240 | | - &qp->sq.max_wr, |
---|
241 | | - wqe_size); |
---|
| 233 | + qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, wqe_size); |
---|
242 | 234 | if (!qp->sq.queue) |
---|
243 | 235 | return -ENOMEM; |
---|
244 | 236 | |
---|
245 | | - err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, context, |
---|
| 237 | + err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, udata, |
---|
246 | 238 | qp->sq.queue->buf, qp->sq.queue->buf_size, |
---|
247 | 239 | &qp->sq.queue->ip); |
---|
248 | 240 | |
---|
.. | .. |
---|
258 | 250 | qp->req.opcode = -1; |
---|
259 | 251 | qp->comp.opcode = -1; |
---|
260 | 252 | |
---|
261 | | - spin_lock_init(&qp->sq.sq_lock); |
---|
262 | | - skb_queue_head_init(&qp->req_pkts); |
---|
263 | | - |
---|
264 | | - rxe_init_task(rxe, &qp->req.task, qp, |
---|
265 | | - rxe_requester, "req"); |
---|
266 | | - rxe_init_task(rxe, &qp->comp.task, qp, |
---|
267 | | - rxe_completer, "comp"); |
---|
| 253 | + rxe_init_task(&qp->req.task, qp, rxe_requester); |
---|
| 254 | + rxe_init_task(&qp->comp.task, qp, rxe_completer); |
---|
268 | 255 | |
---|
269 | 256 | qp->qp_timeout_jiffies = 0; /* Can't be set for UD/UC in modify_qp */ |
---|
270 | 257 | if (init->qp_type == IB_QPT_RC) { |
---|
.. | .. |
---|
276 | 263 | |
---|
277 | 264 | static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, |
---|
278 | 265 | struct ib_qp_init_attr *init, |
---|
279 | | - struct ib_ucontext *context, |
---|
| 266 | + struct ib_udata *udata, |
---|
280 | 267 | struct rxe_create_qp_resp __user *uresp) |
---|
281 | 268 | { |
---|
282 | 269 | int err; |
---|
.. | .. |
---|
297 | 284 | if (!qp->rq.queue) |
---|
298 | 285 | return -ENOMEM; |
---|
299 | 286 | |
---|
300 | | - err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, context, |
---|
| 287 | + err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, udata, |
---|
301 | 288 | qp->rq.queue->buf, qp->rq.queue->buf_size, |
---|
302 | 289 | &qp->rq.queue->ip); |
---|
303 | 290 | if (err) { |
---|
.. | .. |
---|
308 | 295 | } |
---|
309 | 296 | } |
---|
310 | 297 | |
---|
311 | | - spin_lock_init(&qp->rq.producer_lock); |
---|
312 | | - spin_lock_init(&qp->rq.consumer_lock); |
---|
313 | | - |
---|
314 | | - skb_queue_head_init(&qp->resp_pkts); |
---|
315 | | - |
---|
316 | | - rxe_init_task(rxe, &qp->resp.task, qp, |
---|
317 | | - rxe_responder, "resp"); |
---|
| 298 | + rxe_init_task(&qp->resp.task, qp, rxe_responder); |
---|
318 | 299 | |
---|
319 | 300 | qp->resp.opcode = OPCODE_NONE; |
---|
320 | 301 | qp->resp.msn = 0; |
---|
.. | .. |
---|
327 | 308 | int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd, |
---|
328 | 309 | struct ib_qp_init_attr *init, |
---|
329 | 310 | struct rxe_create_qp_resp __user *uresp, |
---|
330 | | - struct ib_pd *ibpd) |
---|
| 311 | + struct ib_pd *ibpd, |
---|
| 312 | + struct ib_udata *udata) |
---|
331 | 313 | { |
---|
332 | 314 | int err; |
---|
333 | 315 | struct rxe_cq *rcq = to_rcq(init->recv_cq); |
---|
334 | 316 | struct rxe_cq *scq = to_rcq(init->send_cq); |
---|
335 | 317 | struct rxe_srq *srq = init->srq ? to_rsrq(init->srq) : NULL; |
---|
336 | | - struct ib_ucontext *context = ibpd->uobject ? ibpd->uobject->context : NULL; |
---|
337 | 318 | |
---|
338 | 319 | rxe_add_ref(pd); |
---|
339 | 320 | rxe_add_ref(rcq); |
---|
.. | .. |
---|
348 | 329 | |
---|
349 | 330 | rxe_qp_init_misc(rxe, qp, init); |
---|
350 | 331 | |
---|
351 | | - err = rxe_qp_init_req(rxe, qp, init, context, uresp); |
---|
| 332 | + err = rxe_qp_init_req(rxe, qp, init, udata, uresp); |
---|
352 | 333 | if (err) |
---|
353 | 334 | goto err1; |
---|
354 | 335 | |
---|
355 | | - err = rxe_qp_init_resp(rxe, qp, init, context, uresp); |
---|
| 336 | + err = rxe_qp_init_resp(rxe, qp, init, udata, uresp); |
---|
356 | 337 | if (err) |
---|
357 | 338 | goto err2; |
---|
358 | 339 | |
---|
.. | .. |
---|
415 | 396 | enum ib_qp_state new_state = (mask & IB_QP_STATE) ? |
---|
416 | 397 | attr->qp_state : cur_state; |
---|
417 | 398 | |
---|
418 | | - if (!ib_modify_qp_is_ok(cur_state, new_state, qp_type(qp), mask, |
---|
419 | | - IB_LINK_LAYER_ETHERNET)) { |
---|
| 399 | + if (!ib_modify_qp_is_ok(cur_state, new_state, qp_type(qp), mask)) { |
---|
420 | 400 | pr_warn("invalid mask or state for qp\n"); |
---|
421 | 401 | goto err1; |
---|
422 | 402 | } |
---|
.. | .. |
---|
430 | 410 | } |
---|
431 | 411 | |
---|
432 | 412 | if (mask & IB_QP_PORT) { |
---|
433 | | - if (attr->port_num != 1) { |
---|
| 413 | + if (!rdma_is_port_valid(&rxe->ib_dev, attr->port_num)) { |
---|
434 | 414 | pr_warn("invalid port %d\n", attr->port_num); |
---|
435 | 415 | goto err1; |
---|
436 | 416 | } |
---|
.. | .. |
---|
445 | 425 | if (mask & IB_QP_ALT_PATH) { |
---|
446 | 426 | if (rxe_av_chk_attr(rxe, &attr->alt_ah_attr)) |
---|
447 | 427 | goto err1; |
---|
448 | | - if (attr->alt_port_num != 1) { |
---|
| 428 | + if (!rdma_is_port_valid(&rxe->ib_dev, attr->alt_port_num)) { |
---|
449 | 429 | pr_warn("invalid alt port %d\n", attr->alt_port_num); |
---|
450 | 430 | goto err1; |
---|
451 | 431 | } |
---|
.. | .. |
---|
627 | 607 | if (mask & IB_QP_QKEY) |
---|
628 | 608 | qp->attr.qkey = attr->qkey; |
---|
629 | 609 | |
---|
630 | | - if (mask & IB_QP_AV) { |
---|
631 | | - rxe_av_from_attr(attr->port_num, &qp->pri_av, &attr->ah_attr); |
---|
632 | | - rxe_av_fill_ip_info(&qp->pri_av, &attr->ah_attr); |
---|
633 | | - } |
---|
| 610 | + if (mask & IB_QP_AV) |
---|
| 611 | + rxe_init_av(&attr->ah_attr, &qp->pri_av); |
---|
634 | 612 | |
---|
635 | 613 | if (mask & IB_QP_ALT_PATH) { |
---|
636 | | - rxe_av_from_attr(attr->alt_port_num, &qp->alt_av, |
---|
637 | | - &attr->alt_ah_attr); |
---|
638 | | - rxe_av_fill_ip_info(&qp->alt_av, &attr->alt_ah_attr); |
---|
| 614 | + rxe_init_av(&attr->alt_ah_attr, &qp->alt_av); |
---|
639 | 615 | qp->attr.alt_port_num = attr->alt_port_num; |
---|
640 | 616 | qp->attr.alt_pkey_index = attr->alt_pkey_index; |
---|
641 | 617 | qp->attr.alt_timeout = attr->alt_timeout; |
---|
.. | .. |
---|
795 | 771 | rxe_cleanup_task(&qp->comp.task); |
---|
796 | 772 | |
---|
797 | 773 | /* flush out any receive wr's or pending requests */ |
---|
798 | | - __rxe_do_task(&qp->req.task); |
---|
| 774 | + if (qp->req.task.func) |
---|
| 775 | + __rxe_do_task(&qp->req.task); |
---|
| 776 | + |
---|
799 | 777 | if (qp->sq.queue) { |
---|
800 | 778 | __rxe_do_task(&qp->comp.task); |
---|
801 | 779 | __rxe_do_task(&qp->req.task); |
---|
.. | .. |
---|
830 | 808 | qp->resp.mr = NULL; |
---|
831 | 809 | } |
---|
832 | 810 | |
---|
833 | | - if (qp_type(qp) == IB_QPT_RC) |
---|
834 | | - sk_dst_reset(qp->sk->sk); |
---|
835 | | - |
---|
836 | 811 | free_rd_atomic_resources(qp); |
---|
837 | 812 | |
---|
838 | | - kernel_sock_shutdown(qp->sk, SHUT_RDWR); |
---|
839 | | - sock_release(qp->sk); |
---|
| 813 | + if (qp->sk) { |
---|
| 814 | + if (qp_type(qp) == IB_QPT_RC) |
---|
| 815 | + sk_dst_reset(qp->sk->sk); |
---|
| 816 | + |
---|
| 817 | + kernel_sock_shutdown(qp->sk, SHUT_RDWR); |
---|
| 818 | + sock_release(qp->sk); |
---|
| 819 | + } |
---|
840 | 820 | } |
---|
841 | 821 | |
---|
842 | 822 | /* called when the last reference to the qp is dropped */ |
---|