]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
IB/mlx4: Fetch XRC SRQ in the CQ polling code
authorShlomo Pongratz <shlomop@mellanox.com>
Wed, 10 Apr 2013 14:26:48 +0000 (14:26 +0000)
committerRoland Dreier <roland@purestorage.com>
Wed, 17 Apr 2013 05:42:55 +0000 (22:42 -0700)
An XRC target QP may redirect to more than one XRC SRQ.  This means
that for work completions associated with a XRC TGT QP, the srq field
in the QP has no usage and the real XRC SRQ need to be retrived using
the information from the XRCETH placed into the CQE, do that.

Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/mlx4/cq.c

index ae67df35dd4d6910945bf728fbd3dde8bca587f0..dab4b5188a27439f3575d9677de8ac8657bddd08 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/mlx4/cq.h>
 #include <linux/mlx4/qp.h>
+#include <linux/mlx4/srq.h>
 #include <linux/slab.h>
 
 #include "mlx4_ib.h"
@@ -585,6 +586,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
        struct mlx4_qp *mqp;
        struct mlx4_ib_wq *wq;
        struct mlx4_ib_srq *srq;
+       struct mlx4_srq *msrq = NULL;
        int is_send;
        int is_error;
        u32 g_mlpath_rqpn;
@@ -653,6 +655,20 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
 
        wc->qp = &(*cur_qp)->ibqp;
 
+       if (wc->qp->qp_type == IB_QPT_XRC_TGT) {
+               u32 srq_num;
+               g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn);
+               srq_num       = g_mlpath_rqpn & 0xffffff;
+               /* SRQ is also in the radix tree */
+               msrq = mlx4_srq_lookup(to_mdev(cq->ibcq.device)->dev,
+                                      srq_num);
+               if (unlikely(!msrq)) {
+                       pr_warn("CQ %06x with entry for unknown SRQN %06x\n",
+                               cq->mcq.cqn, srq_num);
+                       return -EINVAL;
+               }
+       }
+
        if (is_send) {
                wq = &(*cur_qp)->sq;
                if (!(*cur_qp)->sq_signal_bits) {
@@ -666,6 +682,11 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                wqe_ctr = be16_to_cpu(cqe->wqe_index);
                wc->wr_id = srq->wrid[wqe_ctr];
                mlx4_ib_free_srq_wqe(srq, wqe_ctr);
+       } else if (msrq) {
+               srq = to_mibsrq(msrq);
+               wqe_ctr = be16_to_cpu(cqe->wqe_index);
+               wc->wr_id = srq->wrid[wqe_ctr];
+               mlx4_ib_free_srq_wqe(srq, wqe_ctr);
        } else {
                wq        = &(*cur_qp)->rq;
                tail      = wq->tail & (wq->wqe_cnt - 1);