aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaggai Eran <haggaie@mellanox.com>2016-02-29 08:45:10 -0500
committerDoug Ledford <dledford@redhat.com>2016-03-01 11:04:07 -0500
commit83cae2aff53960ab6cf5bb82654201ce43b77fb6 (patch)
tree5100a68cdd6c7d0655c34509478d124ecf5e392e
parentea6dc2036224aaee887f391a1ee8833bea18c68b (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.c48
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 */
447static 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 */
468static 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
446int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr, 482int 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) %