diff options
author | Haggai Eran <haggaie@mellanox.com> | 2016-02-29 08:45:10 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-03-01 11:04:07 -0500 |
commit | 83cae2aff53960ab6cf5bb82654201ce43b77fb6 (patch) | |
tree | 5100a68cdd6c7d0655c34509478d124ecf5e392e | |
parent | ea6dc2036224aaee887f391a1ee8833bea18c68b (diff) |
IB/mlx5: Pick the right GSI transmission QP for sending
Pick the QP to use according to the wr.ud.pkey_index field in the work
request. If the QP doesn't exist, it means the P_Key is zero and the packet
would have been dropped, so just generate a completion and move on.
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/hw/mlx5/gsi.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c index 8d040626abb2..938f6ddca4b3 100644 --- a/drivers/infiniband/hw/mlx5/gsi.c +++ b/drivers/infiniband/hw/mlx5/gsi.c | |||
@@ -443,10 +443,47 @@ static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp *gsi, | |||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | 445 | ||
446 | /* Call with gsi->lock locked */ | ||
447 | static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_gsi_qp *gsi, | ||
448 | struct ib_ud_wr *wr) | ||
449 | { | ||
450 | struct ib_wc wc = { | ||
451 | { .wr_id = wr->wr.wr_id }, | ||
452 | .status = IB_WC_SUCCESS, | ||
453 | .opcode = IB_WC_SEND, | ||
454 | .qp = &gsi->ibqp, | ||
455 | }; | ||
456 | int ret; | ||
457 | |||
458 | ret = mlx5_ib_add_outstanding_wr(gsi, wr, &wc); | ||
459 | if (ret) | ||
460 | return ret; | ||
461 | |||
462 | generate_completions(gsi); | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /* Call with gsi->lock locked */ | ||
468 | static struct ib_qp *get_tx_qp(struct mlx5_ib_gsi_qp *gsi, struct ib_ud_wr *wr) | ||
469 | { | ||
470 | struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); | ||
471 | int qp_index = wr->pkey_index; | ||
472 | |||
473 | if (!mlx5_ib_deth_sqpn_cap(dev)) | ||
474 | return gsi->rx_qp; | ||
475 | |||
476 | if (qp_index >= gsi->num_qps) | ||
477 | return NULL; | ||
478 | |||
479 | return gsi->tx_qps[qp_index]; | ||
480 | } | ||
481 | |||
446 | int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr, | 482 | int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr, |
447 | struct ib_send_wr **bad_wr) | 483 | struct ib_send_wr **bad_wr) |
448 | { | 484 | { |
449 | struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); | 485 | struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp); |
486 | struct ib_qp *tx_qp; | ||
450 | unsigned long flags; | 487 | unsigned long flags; |
451 | int ret; | 488 | int ret; |
452 | 489 | ||
@@ -456,11 +493,20 @@ int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr, | |||
456 | cur_wr.wr.next = NULL; | 493 | cur_wr.wr.next = NULL; |
457 | 494 | ||
458 | spin_lock_irqsave(&gsi->lock, flags); | 495 | spin_lock_irqsave(&gsi->lock, flags); |
496 | tx_qp = get_tx_qp(gsi, &cur_wr); | ||
497 | if (!tx_qp) { | ||
498 | ret = mlx5_ib_gsi_silent_drop(gsi, &cur_wr); | ||
499 | if (ret) | ||
500 | goto err; | ||
501 | spin_unlock_irqrestore(&gsi->lock, flags); | ||
502 | continue; | ||
503 | } | ||
504 | |||
459 | ret = mlx5_ib_add_outstanding_wr(gsi, &cur_wr, NULL); | 505 | ret = mlx5_ib_add_outstanding_wr(gsi, &cur_wr, NULL); |
460 | if (ret) | 506 | if (ret) |
461 | goto err; | 507 | goto err; |
462 | 508 | ||
463 | ret = ib_post_send(gsi->rx_qp, &cur_wr.wr, bad_wr); | 509 | ret = ib_post_send(tx_qp, &cur_wr.wr, bad_wr); |
464 | if (ret) { | 510 | if (ret) { |
465 | /* Undo the effect of adding the outstanding wr */ | 511 | /* Undo the effect of adding the outstanding wr */ |
466 | gsi->outstanding_pi = (gsi->outstanding_pi - 1) % | 512 | gsi->outstanding_pi = (gsi->outstanding_pi - 1) % |