Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2446304dd687488c054d0437f2aeef1ef2bfbd02
Commit:     2446304dd687488c054d0437f2aeef1ef2bfbd02
Parent:     59b0ed121297b57abb2352bdc8313959e7cb5635
Author:     Eli Cohen <[EMAIL PROTECTED]>
AuthorDate: Thu May 17 10:32:41 2007 +0300
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Sun May 20 10:18:04 2007 -0700

    IB/mlx4: Pass send queue sizes from userspace to kernel
    
    Pass the number of WQEs for the send queue and their size from userspace
    to the kernel to avoid having to keep the QP size calculations in sync
    between the kernel driver and libmlx4.  This fixes a bug seen with the
    current mlx4_ib driver and current libmlx4 caused by a difference in the
    calculated sizes for SQ WQEs.  Also, this gives more flexibility for
    userspace to experiment with using multiple WQE BBs for a single SQ WQE.
    
    Signed-off-by: Eli Cohen <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/mlx4/qp.c   |   63 +++++++++++++++++++++++++++---------
 drivers/infiniband/hw/mlx4/user.h |    5 ++-
 2 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 5706f98..a824bc5 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -188,14 +188,32 @@ static int send_wqe_overhead(enum ib_qp_type type)
        }
 }
 
-static int set_qp_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
-                      enum ib_qp_type type, struct mlx4_ib_qp *qp)
+static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
+                      struct mlx4_ib_qp *qp)
 {
-       /* Sanity check QP size before proceeding */
+       /* 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;
+
+       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);
+
+       cap->max_recv_wr  = qp->rq.max;
+       cap->max_recv_sge = qp->rq.max_gs;
+
+       return 0;
+}
+
+static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
+                             enum ib_qp_type type, struct mlx4_ib_qp *qp)
+{
+       /* Sanity check SQ size before proceeding */
        if (cap->max_send_wr     > dev->dev->caps.max_wqes  ||
-           cap->max_recv_wr     > dev->dev->caps.max_wqes  ||
            cap->max_send_sge    > dev->dev->caps.max_sq_sg ||
-           cap->max_recv_sge    > dev->dev->caps.max_rq_sg ||
            cap->max_inline_data + send_wqe_overhead(type) +
            sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz)
                return -EINVAL;
@@ -208,12 +226,7 @@ static int set_qp_size(struct mlx4_ib_dev *dev, struct 
ib_qp_cap *cap,
            cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg)
                return -EINVAL;
 
-       qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 
0;
-       qp->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 
0;
-
-       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->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 
1;
 
        qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge *
                                                        sizeof (struct 
mlx4_wqe_data_seg),
@@ -233,16 +246,26 @@ static int set_qp_size(struct mlx4_ib_dev *dev, struct 
ib_qp_cap *cap,
                qp->sq.offset = 0;
        }
 
-       cap->max_send_wr  = qp->sq.max;
-       cap->max_recv_wr  = qp->rq.max;
-       cap->max_send_sge = qp->sq.max_gs;
-       cap->max_recv_sge = qp->rq.max_gs;
+       cap->max_send_wr     = qp->sq.max;
+       cap->max_send_sge    = qp->sq.max_gs;
        cap->max_inline_data = (1 << qp->sq.wqe_shift) - 
send_wqe_overhead(type) -
                sizeof (struct mlx4_wqe_inline_seg);
 
        return 0;
 }
 
+static int set_user_sq_size(struct mlx4_ib_qp *qp,
+                           struct mlx4_ib_create_qp *ucmd)
+{
+       qp->sq.max       = 1 << ucmd->log_sq_bb_count;
+       qp->sq.wqe_shift = ucmd->log_sq_stride;
+
+       qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) +
+               (qp->sq.max << qp->sq.wqe_shift);
+
+       return 0;
+}
+
 static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata, int sqpn, struct mlx4_ib_qp 
*qp)
@@ -264,7 +287,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_qp_size(dev, &init_attr->cap, init_attr->qp_type, qp);
+       err = set_rq_size(dev, &init_attr->cap, qp);
        if (err)
                goto err;
 
@@ -276,6 +299,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, 
struct ib_pd *pd,
                        goto err;
                }
 
+               err = set_user_sq_size(qp, &ucmd);
+               if (err)
+                       goto err;
+
                qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
                                       qp->buf_size, 0);
                if (IS_ERR(qp->umem)) {
@@ -297,6 +324,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, 
struct ib_pd *pd,
                if (err)
                        goto err_mtt;
        } else {
+               err = set_kernel_sq_size(dev, &init_attr->cap, 
init_attr->qp_type, qp);
+               if (err)
+                       goto err;
+
                err = mlx4_ib_db_alloc(dev, &qp->db, 0);
                if (err)
                        goto err;
diff --git a/drivers/infiniband/hw/mlx4/user.h 
b/drivers/infiniband/hw/mlx4/user.h
index 5b8eddc..88c72d5 100644
--- a/drivers/infiniband/hw/mlx4/user.h
+++ b/drivers/infiniband/hw/mlx4/user.h
@@ -39,7 +39,7 @@
  * Increment this value if any changes that break userspace ABI
  * compatibility are made.
  */
-#define MLX4_IB_UVERBS_ABI_VERSION     1
+#define MLX4_IB_UVERBS_ABI_VERSION     2
 
 /*
  * Make sure that all structs defined in this file remain laid out so
@@ -87,6 +87,9 @@ struct mlx4_ib_create_srq_resp {
 struct mlx4_ib_create_qp {
        __u64   buf_addr;
        __u64   db_addr;
+        __u8   log_sq_bb_count;
+        __u8   log_sq_stride;
+        __u8   reserved[6];
 };
 
 #endif /* MLX4_IB_USER_H */
-
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