]> git.karo-electronics.de Git - linux-beck.git/commitdiff
IB/mlx5: Pick the right GSI transmission QP for sending
authorHaggai Eran <haggaie@mellanox.com>
Mon, 29 Feb 2016 13:45:10 +0000 (15:45 +0200)
committerDoug Ledford <dledford@redhat.com>
Tue, 1 Mar 2016 16:04:07 +0000 (11:04 -0500)
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>
drivers/infiniband/hw/mlx5/gsi.c

index 8d040626abb286a9bb48a88c1bf6ddcf5c0d75ae..938f6ddca4b34e55de1cb1f466982c32cf60754f 100644 (file)
@@ -443,10 +443,47 @@ static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp *gsi,
        return 0;
 }
 
+/* Call with gsi->lock locked */
+static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_gsi_qp *gsi,
+                                   struct ib_ud_wr *wr)
+{
+       struct ib_wc wc = {
+               { .wr_id = wr->wr.wr_id },
+               .status = IB_WC_SUCCESS,
+               .opcode = IB_WC_SEND,
+               .qp = &gsi->ibqp,
+       };
+       int ret;
+
+       ret = mlx5_ib_add_outstanding_wr(gsi, wr, &wc);
+       if (ret)
+               return ret;
+
+       generate_completions(gsi);
+
+       return 0;
+}
+
+/* Call with gsi->lock locked */
+static struct ib_qp *get_tx_qp(struct mlx5_ib_gsi_qp *gsi, struct ib_ud_wr *wr)
+{
+       struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device);
+       int qp_index = wr->pkey_index;
+
+       if (!mlx5_ib_deth_sqpn_cap(dev))
+               return gsi->rx_qp;
+
+       if (qp_index >= gsi->num_qps)
+               return NULL;
+
+       return gsi->tx_qps[qp_index];
+}
+
 int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr,
                          struct ib_send_wr **bad_wr)
 {
        struct mlx5_ib_gsi_qp *gsi = gsi_qp(qp);
+       struct ib_qp *tx_qp;
        unsigned long flags;
        int ret;
 
@@ -456,11 +493,20 @@ int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr,
                cur_wr.wr.next = NULL;
 
                spin_lock_irqsave(&gsi->lock, flags);
+               tx_qp = get_tx_qp(gsi, &cur_wr);
+               if (!tx_qp) {
+                       ret = mlx5_ib_gsi_silent_drop(gsi, &cur_wr);
+                       if (ret)
+                               goto err;
+                       spin_unlock_irqrestore(&gsi->lock, flags);
+                       continue;
+               }
+
                ret = mlx5_ib_add_outstanding_wr(gsi, &cur_wr, NULL);
                if (ret)
                        goto err;
 
-               ret = ib_post_send(gsi->rx_qp, &cur_wr.wr, bad_wr);
+               ret = ib_post_send(tx_qp, &cur_wr.wr, bad_wr);
                if (ret) {
                        /* Undo the effect of adding the outstanding wr */
                        gsi->outstanding_pi = (gsi->outstanding_pi - 1) %