Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a4cd7ed86ff511aebcc97675937039f2321d6987
Commit:     a4cd7ed86ff511aebcc97675937039f2321d6987
Parent:     bf2944bd56c7a48cc3962a860dbc4ceee6b1ace8
Author:     Roland Dreier <[EMAIL PROTECTED]>
AuthorDate: Thu Jun 7 23:24:39 2007 -0700
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Thu Jun 7 23:24:39 2007 -0700

    IB/mlx4: Make sure RQ allocation is always valid
    
    QPs attached to an SRQ must never have their own RQ, and QPs not
    attached to SRQs must have an RQ with at least 1 entry.  Enforce all
    of this in set_rq_size().
    
    Based on a patch by Eli Cohen <[EMAIL PROTECTED]>.
    
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/mlx4/qp.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index cd22975..5c6d054 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -189,18 +189,28 @@ static int send_wqe_overhead(enum ib_qp_type type)
 }
 
 static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
-                      struct mlx4_ib_qp *qp)
+                      int is_user, int has_srq, struct mlx4_ib_qp *qp)
 {
        /* Sanity check RQ size before proceeding */
        if (cap->max_recv_wr  > dev->dev->caps.max_wqes  ||
            cap->max_recv_sge > dev->dev->caps.max_rq_sg)
                return -EINVAL;
 
-       qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 
0;
+       if (has_srq) {
+               /* QPs attached to an SRQ should have no RQ */
+               if (cap->max_recv_wr)
+                       return -EINVAL;
 
-       qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
-                                                   sizeof (struct 
mlx4_wqe_data_seg)));
-       qp->rq.max_gs    = (1 << qp->rq.wqe_shift) / sizeof (struct 
mlx4_wqe_data_seg);
+               qp->rq.max = qp->rq.max_gs = 0;
+       } else {
+               /* HW requires >= 1 RQ entry with >= 1 gather entry */
+               if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
+                       return -EINVAL;
+
+               qp->rq.max       = roundup_pow_of_two(max(1, cap->max_recv_wr));
+               qp->rq.max_gs    = roundup_pow_of_two(max(1, 
cap->max_recv_sge));
+               qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct 
mlx4_wqe_data_seg));
+       }
 
        cap->max_recv_wr  = qp->rq.max;
        cap->max_recv_sge = qp->rq.max_gs;
@@ -285,7 +295,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct 
ib_pd *pd,
        qp->sq.head         = 0;
        qp->sq.tail         = 0;
 
-       err = set_rq_size(dev, &init_attr->cap, qp);
+       err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, 
!!init_attr->srq, qp);
        if (err)
                goto err;
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to