1 /*- 2 * Copyright (c) 2016-2020, Mellanox Technologies, Ltd. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 #include "opt_rss.h" 29 #include "opt_ratelimit.h" 30 31 #include <dev/mlx5/mlx5_ib/mlx5_ib.h> 32 33 struct mlx5_ib_gsi_wr { 34 struct ib_cqe cqe; 35 struct ib_wc wc; 36 int send_flags; 37 bool completed:1; 38 }; 39 40 struct mlx5_ib_gsi_qp { 41 struct ib_qp ibqp; 42 struct ib_qp *rx_qp; 43 u8 port_num; 44 struct ib_qp_cap cap; 45 enum ib_sig_type sq_sig_type; 46 /* Serialize qp state modifications */ 47 struct mutex mutex; 48 struct ib_cq *cq; 49 struct mlx5_ib_gsi_wr *outstanding_wrs; 50 u32 outstanding_pi, outstanding_ci; 51 int num_qps; 52 /* Protects access to the tx_qps. Post send operations synchronize 53 * with tx_qp creation in setup_qp(). Also protects the 54 * outstanding_wrs array and indices. 55 */ 56 spinlock_t lock; 57 struct ib_qp **tx_qps; 58 }; 59 60 static struct mlx5_ib_gsi_qp *gsi_qp(struct ib_qp *qp) 61 { 62 return container_of(qp, struct mlx5_ib_gsi_qp, ibqp); 63 } 64 65 static bool mlx5_ib_deth_sqpn_cap(struct mlx5_ib_dev *dev) 66 { 67 return MLX5_CAP_GEN(dev->mdev, set_deth_sqpn); 68 } 69 70 /* Call with gsi->lock locked */ 71 static void generate_completions(struct mlx5_ib_gsi_qp *gsi) 72 { 73 struct ib_cq *gsi_cq = gsi->ibqp.send_cq; 74 struct mlx5_ib_gsi_wr *wr; 75 u32 index; 76 77 for (index = gsi->outstanding_ci; index != gsi->outstanding_pi; 78 index++) { 79 wr = &gsi->outstanding_wrs[index % gsi->cap.max_send_wr]; 80 81 if (!wr->completed) 82 break; 83 84 if (gsi->sq_sig_type == IB_SIGNAL_ALL_WR || 85 wr->send_flags & IB_SEND_SIGNALED) 86 WARN_ON_ONCE(mlx5_ib_generate_wc(gsi_cq, &wr->wc)); 87 88 wr->completed = false; 89 } 90 91 gsi->outstanding_ci = index; 92 } 93 94 static void handle_single_completion(struct ib_cq *cq, struct ib_wc *wc) 95 { 96 struct mlx5_ib_gsi_qp *gsi = cq->cq_context; 97 struct mlx5_ib_gsi_wr *wr = 98 container_of(wc->wr_cqe, struct mlx5_ib_gsi_wr, cqe); 99 u64 wr_id; 100 unsigned long flags; 101 102 spin_lock_irqsave(&gsi->lock, flags); 103 wr->completed = true; 104 wr_id = wr->wc.wr_id; 105 wr->wc = *wc; 106 wr->wc.wr_id = wr_id; 107 wr->wc.qp = &gsi->ibqp; 108 109 generate_completions(gsi); 110 spin_unlock_irqrestore(&gsi->lock, flags); 111 } 112 113 struct ib_qp *mlx5_ib_gsi_create_qp(struct ib_pd *pd, 114 struct ib_qp_init_attr *init_attr) 115 { 116 struct mlx5_ib_dev *dev = to_mdev(pd->device); 117 struct mlx5_ib_gsi_qp *gsi; 118 struct ib_qp_init_attr hw_init_attr = *init_attr; 119 const u8 port_num = init_attr->port_num; 120 const int num_pkeys = pd->device->attrs.max_pkeys; 121 const int num_qps = mlx5_ib_deth_sqpn_cap(dev) ? num_pkeys : 0; 122 int ret; 123 124 mlx5_ib_dbg(dev, "creating GSI QP\n"); 125 126 if (port_num > ARRAY_SIZE(dev->devr.ports) || port_num < 1) { 127 mlx5_ib_warn(dev, 128 "invalid port number %d during GSI QP creation\n", 129 port_num); 130 return ERR_PTR(-EINVAL); 131 } 132 133 gsi = kzalloc(sizeof(*gsi), GFP_KERNEL); 134 if (!gsi) 135 return ERR_PTR(-ENOMEM); 136 137 gsi->tx_qps = kcalloc(num_qps, sizeof(*gsi->tx_qps), GFP_KERNEL); 138 if (!gsi->tx_qps) { 139 ret = -ENOMEM; 140 goto err_free; 141 } 142 143 gsi->outstanding_wrs = kcalloc(init_attr->cap.max_send_wr, 144 sizeof(*gsi->outstanding_wrs), 145 GFP_KERNEL); 146 if (!gsi->outstanding_wrs) { 147 ret = -ENOMEM; 148 goto err_free_tx; 149 } 150 151 mutex_init(&gsi->mutex); 152 153 mutex_lock(&dev->devr.mutex); 154 155 if (dev->devr.ports[port_num - 1].gsi) { 156 mlx5_ib_warn(dev, "GSI QP already exists on port %d\n", 157 port_num); 158 ret = -EBUSY; 159 goto err_free_wrs; 160 } 161 gsi->num_qps = num_qps; 162 spin_lock_init(&gsi->lock); 163 164 gsi->cap = init_attr->cap; 165 gsi->sq_sig_type = init_attr->sq_sig_type; 166 gsi->ibqp.qp_num = 1; 167 gsi->port_num = port_num; 168 169 gsi->cq = ib_alloc_cq(pd->device, gsi, init_attr->cap.max_send_wr, 0, 170 IB_POLL_SOFTIRQ); 171 if (IS_ERR(gsi->cq)) { 172 mlx5_ib_warn(dev, "unable to create send CQ for GSI QP. error %ld\n", 173 PTR_ERR(gsi->cq)); 174 ret = PTR_ERR(gsi->cq); 175 goto err_free_wrs; 176 } 177 178 hw_init_attr.qp_type = MLX5_IB_QPT_HW_GSI; 179 hw_init_attr.send_cq = gsi->cq; 180 if (num_qps) { 181 hw_init_attr.cap.max_send_wr = 0; 182 hw_init_attr.cap.max_send_sge = 0; 183 hw_init_attr.cap.max_inline_data = 0; 184 } 185 gsi->rx_qp = ib_create_qp(pd, &hw_init_attr); 186 if (IS_ERR(gsi->rx_qp)) { 187 mlx5_ib_warn(dev, "unable to create hardware GSI QP. error %ld\n", 188 PTR_ERR(gsi->rx_qp)); 189 ret = PTR_ERR(gsi->rx_qp); 190 goto err_destroy_cq; 191 } 192 193 dev->devr.ports[init_attr->port_num - 1].gsi = gsi; 194 195 mutex_unlock(&dev->devr.mutex); 196 197 return &gsi->ibqp; 198 199 err_destroy_cq: 200 ib_free_cq(gsi->cq); 201 err_free_wrs: 202 mutex_unlock(&dev->devr.mutex); 203 kfree(gsi->outstanding_wrs); 204 err_free_tx: 205 kfree(gsi->tx_qps); 206 err_free: 207 kfree(gsi); 208 return ERR_PTR(ret); 209 } 210 211 int mlx5_ib_gsi_destroy_qp(struct ib_qp *qp) 212 { 213 struct mlx5_ib_dev *dev = to_mdev(qp->device); 214 struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); 215 const int port_num = gsi->port_num; 216 int qp_index; 217 int ret; 218 219 mlx5_ib_dbg(dev, "destroying GSI QP\n"); 220 221 mutex_lock(&dev->devr.mutex); 222 ret = ib_destroy_qp(gsi->rx_qp); 223 if (ret) { 224 mlx5_ib_warn(dev, "unable to destroy hardware GSI QP. error %d\n", 225 ret); 226 mutex_unlock(&dev->devr.mutex); 227 return ret; 228 } 229 dev->devr.ports[port_num - 1].gsi = NULL; 230 mutex_unlock(&dev->devr.mutex); 231 gsi->rx_qp = NULL; 232 233 for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) { 234 if (!gsi->tx_qps[qp_index]) 235 continue; 236 WARN_ON_ONCE(ib_destroy_qp(gsi->tx_qps[qp_index])); 237 gsi->tx_qps[qp_index] = NULL; 238 } 239 240 ib_free_cq(gsi->cq); 241 242 kfree(gsi->outstanding_wrs); 243 kfree(gsi->tx_qps); 244 kfree(gsi); 245 246 return 0; 247 } 248 249 static struct ib_qp *create_gsi_ud_qp(struct mlx5_ib_gsi_qp *gsi) 250 { 251 struct ib_pd *pd = gsi->rx_qp->pd; 252 struct ib_qp_init_attr init_attr = { 253 .event_handler = gsi->rx_qp->event_handler, 254 .qp_context = gsi->rx_qp->qp_context, 255 .send_cq = gsi->cq, 256 .recv_cq = gsi->rx_qp->recv_cq, 257 .cap = { 258 .max_send_wr = gsi->cap.max_send_wr, 259 .max_send_sge = gsi->cap.max_send_sge, 260 .max_inline_data = gsi->cap.max_inline_data, 261 }, 262 .sq_sig_type = gsi->sq_sig_type, 263 .qp_type = IB_QPT_UD, 264 .create_flags = MLX5_IB_QP_CREATE_SQPN_QP1, 265 }; 266 267 return ib_create_qp(pd, &init_attr); 268 } 269 270 static int modify_to_rts(struct mlx5_ib_gsi_qp *gsi, struct ib_qp *qp, 271 u16 qp_index) 272 { 273 struct mlx5_ib_dev *dev = to_mdev(qp->device); 274 struct ib_qp_attr attr; 275 int mask; 276 int ret; 277 278 mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_QKEY | IB_QP_PORT; 279 attr.qp_state = IB_QPS_INIT; 280 attr.pkey_index = qp_index; 281 attr.qkey = IB_QP1_QKEY; 282 attr.port_num = gsi->port_num; 283 ret = ib_modify_qp(qp, &attr, mask); 284 if (ret) { 285 mlx5_ib_err(dev, "could not change QP%d state to INIT: %d\n", 286 qp->qp_num, ret); 287 return ret; 288 } 289 290 attr.qp_state = IB_QPS_RTR; 291 ret = ib_modify_qp(qp, &attr, IB_QP_STATE); 292 if (ret) { 293 mlx5_ib_err(dev, "could not change QP%d state to RTR: %d\n", 294 qp->qp_num, ret); 295 return ret; 296 } 297 298 attr.qp_state = IB_QPS_RTS; 299 attr.sq_psn = 0; 300 ret = ib_modify_qp(qp, &attr, IB_QP_STATE | IB_QP_SQ_PSN); 301 if (ret) { 302 mlx5_ib_err(dev, "could not change QP%d state to RTS: %d\n", 303 qp->qp_num, ret); 304 return ret; 305 } 306 307 return 0; 308 } 309 310 static void setup_qp(struct mlx5_ib_gsi_qp *gsi, u16 qp_index) 311 { 312 struct ib_device *device = gsi->rx_qp->device; 313 struct mlx5_ib_dev *dev = to_mdev(device); 314 struct ib_qp *qp; 315 unsigned long flags; 316 u16 pkey; 317 int ret; 318 319 ret = ib_query_pkey(device, gsi->port_num, qp_index, &pkey); 320 if (ret) { 321 mlx5_ib_warn(dev, "unable to read P_Key at port %d, index %d\n", 322 gsi->port_num, qp_index); 323 return; 324 } 325 326 if (!pkey) { 327 mlx5_ib_dbg(dev, "invalid P_Key at port %d, index %d. Skipping.\n", 328 gsi->port_num, qp_index); 329 return; 330 } 331 332 spin_lock_irqsave(&gsi->lock, flags); 333 qp = gsi->tx_qps[qp_index]; 334 spin_unlock_irqrestore(&gsi->lock, flags); 335 if (qp) { 336 mlx5_ib_dbg(dev, "already existing GSI TX QP at port %d, index %d. Skipping\n", 337 gsi->port_num, qp_index); 338 return; 339 } 340 341 qp = create_gsi_ud_qp(gsi); 342 if (IS_ERR(qp)) { 343 mlx5_ib_warn(dev, "unable to create hardware UD QP for GSI: %ld\n", 344 PTR_ERR(qp)); 345 return; 346 } 347 348 ret = modify_to_rts(gsi, qp, qp_index); 349 if (ret) 350 goto err_destroy_qp; 351 352 spin_lock_irqsave(&gsi->lock, flags); 353 WARN_ON_ONCE(gsi->tx_qps[qp_index]); 354 gsi->tx_qps[qp_index] = qp; 355 spin_unlock_irqrestore(&gsi->lock, flags); 356 357 return; 358 359 err_destroy_qp: 360 WARN_ON_ONCE(qp); 361 } 362 363 static void setup_qps(struct mlx5_ib_gsi_qp *gsi) 364 { 365 u16 qp_index; 366 367 for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) 368 setup_qp(gsi, qp_index); 369 } 370 371 int mlx5_ib_gsi_modify_qp(struct ib_qp *qp, struct ib_qp_attr *attr, 372 int attr_mask) 373 { 374 struct mlx5_ib_dev *dev = to_mdev(qp->device); 375 struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); 376 int ret; 377 378 mlx5_ib_dbg(dev, "modifying GSI QP to state %d\n", attr->qp_state); 379 380 mutex_lock(&gsi->mutex); 381 ret = ib_modify_qp(gsi->rx_qp, attr, attr_mask); 382 if (ret) { 383 mlx5_ib_warn(dev, "unable to modify GSI rx QP: %d\n", ret); 384 goto unlock; 385 } 386 387 if (to_mqp(gsi->rx_qp)->state == IB_QPS_RTS) 388 setup_qps(gsi); 389 390 unlock: 391 mutex_unlock(&gsi->mutex); 392 393 return ret; 394 } 395 396 int mlx5_ib_gsi_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, 397 int qp_attr_mask, 398 struct ib_qp_init_attr *qp_init_attr) 399 { 400 struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); 401 int ret; 402 403 mutex_lock(&gsi->mutex); 404 ret = ib_query_qp(gsi->rx_qp, qp_attr, qp_attr_mask, qp_init_attr); 405 qp_init_attr->cap = gsi->cap; 406 mutex_unlock(&gsi->mutex); 407 408 return ret; 409 } 410 411 /* Call with gsi->lock locked */ 412 static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp *gsi, 413 struct ib_ud_wr *wr, struct ib_wc *wc) 414 { 415 struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); 416 struct mlx5_ib_gsi_wr *gsi_wr; 417 418 if (gsi->outstanding_pi == gsi->outstanding_ci + gsi->cap.max_send_wr) { 419 mlx5_ib_warn(dev, "no available GSI work request.\n"); 420 return -ENOMEM; 421 } 422 423 gsi_wr = &gsi->outstanding_wrs[gsi->outstanding_pi % 424 gsi->cap.max_send_wr]; 425 gsi->outstanding_pi++; 426 427 if (!wc) { 428 memset(&gsi_wr->wc, 0, sizeof(gsi_wr->wc)); 429 gsi_wr->wc.pkey_index = wr->pkey_index; 430 gsi_wr->wc.wr_id = wr->wr.wr_id; 431 } else { 432 gsi_wr->wc = *wc; 433 gsi_wr->completed = true; 434 } 435 436 gsi_wr->cqe.done = &handle_single_completion; 437 wr->wr.wr_cqe = &gsi_wr->cqe; 438 439 return 0; 440 } 441 442 /* Call with gsi->lock locked */ 443 static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_gsi_qp *gsi, 444 struct ib_ud_wr *wr) 445 { 446 struct ib_wc wc = { 447 { .wr_id = wr->wr.wr_id }, 448 .status = IB_WC_SUCCESS, 449 .opcode = IB_WC_SEND, 450 .qp = &gsi->ibqp, 451 }; 452 int ret; 453 454 ret = mlx5_ib_add_outstanding_wr(gsi, wr, &wc); 455 if (ret) 456 return ret; 457 458 generate_completions(gsi); 459 460 return 0; 461 } 462 463 /* Call with gsi->lock locked */ 464 static struct ib_qp *get_tx_qp(struct mlx5_ib_gsi_qp *gsi, struct ib_ud_wr *wr) 465 { 466 struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); 467 int qp_index = wr->pkey_index; 468 469 if (!mlx5_ib_deth_sqpn_cap(dev)) 470 return gsi->rx_qp; 471 472 if (qp_index >= gsi->num_qps) 473 return NULL; 474 475 return gsi->tx_qps[qp_index]; 476 } 477 478 int mlx5_ib_gsi_post_send(struct ib_qp *qp, const struct ib_send_wr *wr, 479 const struct ib_send_wr **bad_wr) 480 { 481 struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); 482 struct ib_qp *tx_qp; 483 unsigned long flags; 484 int ret; 485 486 for (; wr; wr = wr->next) { 487 struct ib_ud_wr cur_wr = *ud_wr(wr); 488 489 cur_wr.wr.next = NULL; 490 491 spin_lock_irqsave(&gsi->lock, flags); 492 tx_qp = get_tx_qp(gsi, &cur_wr); 493 if (!tx_qp) { 494 ret = mlx5_ib_gsi_silent_drop(gsi, &cur_wr); 495 if (ret) 496 goto err; 497 spin_unlock_irqrestore(&gsi->lock, flags); 498 continue; 499 } 500 501 ret = mlx5_ib_add_outstanding_wr(gsi, &cur_wr, NULL); 502 if (ret) 503 goto err; 504 505 ret = ib_post_send(tx_qp, &cur_wr.wr, bad_wr); 506 if (ret) { 507 /* Undo the effect of adding the outstanding wr */ 508 gsi->outstanding_pi = (gsi->outstanding_pi - 1) % 509 gsi->cap.max_send_wr; 510 goto err; 511 } 512 spin_unlock_irqrestore(&gsi->lock, flags); 513 } 514 515 return 0; 516 517 err: 518 spin_unlock_irqrestore(&gsi->lock, flags); 519 *bad_wr = wr; 520 return ret; 521 } 522 523 int mlx5_ib_gsi_post_recv(struct ib_qp *qp, const struct ib_recv_wr *wr, 524 const struct ib_recv_wr **bad_wr) 525 { 526 struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); 527 528 return ib_post_recv(gsi->rx_qp, wr, bad_wr); 529 } 530 531 void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp *gsi) 532 { 533 if (!gsi) 534 return; 535 536 mutex_lock(&gsi->mutex); 537 setup_qps(gsi); 538 mutex_unlock(&gsi->mutex); 539 } 540