aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@mellanox.co.il>2005-11-09 18:25:08 +0000
committerRoland Dreier <rolandd@cisco.com>2006-11-09 19:57:03 -0800
commitf1d68e3ff9828c704262ef2e42fbcc1e05523ab9 (patch)
tree413322b9c5ffe4d14ff1b79b5dee7ffffed6f02f
parentb8b7c75629a62b2bed1a38ce07cb0bae7c34ddfc (diff)
downloadlibmthca-f1d68e3ff9828c704262ef2e42fbcc1e05523ab9.tar.gz
Handle kernel uverbs ABI version 4
Update to handle new kernel ABI 4, which has the kernel compute exact capabilities for QPs. Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il> Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--ChangeLog5
-rw-r--r--src/mthca.h3
-rw-r--r--src/qp.c82
-rw-r--r--src/verbs.c6
4 files changed, 48 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index e0d42bc..68f197a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-11-08 Roland Dreier <roland@cisco.com>
+
+ * src/qp.c, src/verbs.c, src/mthca.h: Delegate setting of QP
+ capabilities (max_sge, max_inline_data, etc) to kernel.
+
2005-11-04 Roland Dreier <roland@cisco.com>
* src/verbs.c (mthca_destroy_qp): Clean CQEs when we destroy a QP.
diff --git a/src/mthca.h b/src/mthca.h
index ce8b8dc..486bcfd 100644
--- a/src/mthca.h
+++ b/src/mthca.h
@@ -177,6 +177,7 @@ struct mthca_qp {
void *buf;
uint64_t *wrid;
int send_wqe_offset;
+ int max_inline_data;
int buf_size;
struct mthca_wq sq;
struct mthca_wq rq;
@@ -319,8 +320,6 @@ extern int mthca_arbel_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);
extern int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
enum ibv_qp_type type, struct mthca_qp *qp);
-extern void mthca_return_cap(struct ibv_pd *pd, struct mthca_qp *qp,
- enum ibv_qp_type type, struct ibv_qp_cap *cap);
extern struct mthca_qp *mthca_find_qp(struct mthca_context *ctx, uint32_t qpn);
extern int mthca_store_qp(struct mthca_context *ctx, uint32_t qpn, struct mthca_qp *qp);
extern void mthca_clear_qp(struct mthca_context *ctx, uint32_t qpn);
diff --git a/src/qp.c b/src/qp.c
index 9d1a69c..0c46472 100644
--- a/src/qp.c
+++ b/src/qp.c
@@ -216,7 +216,6 @@ int mthca_tavor_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
if (wr->send_flags & IBV_SEND_INLINE) {
struct mthca_inline_seg *seg = wqe;
- int max_size = (1 << qp->sq.wqe_shift) - sizeof *seg - size * 16;
int s = 0;
wqe += sizeof *seg;
@@ -225,7 +224,7 @@ int mthca_tavor_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
s += sge->length;
- if (s > max_size) {
+ if (s > qp->max_inline_data) {
ret = -1;
*bad_wr = wr;
goto out;
@@ -515,7 +514,6 @@ int mthca_arbel_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
if (wr->send_flags & IBV_SEND_INLINE) {
struct mthca_inline_seg *seg = wqe;
- int max_size = (1 << qp->sq.wqe_shift) - sizeof *seg - size * 16;
int s = 0;
wqe += sizeof *seg;
@@ -524,7 +522,7 @@ int mthca_arbel_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
s += sge->length;
- if (s > max_size) {
+ if (s > qp->max_inline_data) {
ret = -1;
*bad_wr = wr;
goto out;
@@ -683,12 +681,14 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
enum ibv_qp_type type, struct mthca_qp *qp)
{
int size;
+ int max_sq_sge;
qp->rq.max_gs = cap->max_recv_sge;
- qp->sq.max_gs = align(cap->max_inline_data + sizeof (struct mthca_inline_seg),
+ qp->sq.max_gs = cap->max_send_sge;
+ max_sq_sge = align(cap->max_inline_data + sizeof (struct mthca_inline_seg),
sizeof (struct mthca_data_seg)) / sizeof (struct mthca_data_seg);
- if (qp->sq.max_gs < cap->max_send_sge)
- qp->sq.max_gs = cap->max_send_sge;
+ if (max_sq_sge < cap->max_send_sge)
+ max_sq_sge = cap->max_send_sge;
qp->wrid = malloc((qp->rq.max + qp->sq.max) * sizeof (uint64_t));
if (!qp->wrid)
@@ -701,20 +701,42 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
qp->rq.wqe_shift++)
; /* nothing */
- size = sizeof (struct mthca_next_seg) +
- qp->sq.max_gs * sizeof (struct mthca_data_seg);
+ size = max_sq_sge * sizeof (struct mthca_data_seg);
switch (type) {
case IBV_QPT_UD:
- if (mthca_is_memfree(pd->context))
- size += sizeof (struct mthca_arbel_ud_seg);
- else
- size += sizeof (struct mthca_tavor_ud_seg);
+ size += mthca_is_memfree(pd->context) ?
+ sizeof (struct mthca_arbel_ud_seg) :
+ sizeof (struct mthca_tavor_ud_seg);
+ break;
+
+ case IBV_QPT_UC:
+ size += sizeof (struct mthca_raddr_seg);
+ break;
+
+ case IBV_QPT_RC:
+ size += sizeof (struct mthca_raddr_seg);
+ /*
+ * An atomic op will require an atomic segment, a
+ * remote address segment and one scatter entry.
+ */
+ if (size < (sizeof (struct mthca_atomic_seg) +
+ sizeof (struct mthca_raddr_seg) +
+ sizeof (struct mthca_data_seg)))
+ size = (sizeof (struct mthca_atomic_seg) +
+ sizeof (struct mthca_raddr_seg) +
+ sizeof (struct mthca_data_seg));
break;
+
default:
- /* bind seg is as big as atomic + raddr segs */
- size += sizeof (struct mthca_bind_seg);
+ break;
}
+ /* Make sure that we have enough space for a bind request */
+ if (size < sizeof (struct mthca_bind_seg))
+ size = sizeof (struct mthca_bind_seg);
+
+ size += sizeof (struct mthca_next_seg);
+
for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
qp->sq.wqe_shift++)
; /* nothing */
@@ -767,36 +789,6 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
return 0;
}
-void mthca_return_cap(struct ibv_pd *pd, struct mthca_qp *qp,
- enum ibv_qp_type type, struct ibv_qp_cap *cap)
-{
- /*
- * Maximum inline data size is the full WQE size less the size
- * of the next segment, inline segment and other non-data segments.
- */
- cap->max_inline_data = (1 << qp->sq.wqe_shift) -
- sizeof (struct mthca_next_seg) -
- sizeof (struct mthca_inline_seg);
-
- switch (type) {
- case IBV_QPT_UD:
- if (mthca_is_memfree(pd->context))
- cap->max_inline_data -= sizeof (struct mthca_arbel_ud_seg);
- else
- cap->max_inline_data -= sizeof (struct mthca_tavor_ud_seg);
- break;
-
- default:
- cap->max_inline_data -= sizeof (struct mthca_raddr_seg);
- break;
- }
-
- 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;
-}
-
struct mthca_qp *mthca_find_qp(struct mthca_context *ctx, uint32_t qpn)
{
int tind = (qpn & (ctx->num_qps - 1)) >> ctx->qp_table_shift;
diff --git a/src/verbs.c b/src/verbs.c
index c001a82..1dba4f2 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -476,7 +476,11 @@ struct ibv_qp *mthca_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
if (ret)
goto err_destroy;
- mthca_return_cap(pd, qp, attr->qp_type, &attr->cap);
+ qp->sq.max = attr->cap.max_send_wr;
+ qp->rq.max = attr->cap.max_recv_wr;
+ qp->sq.max_gs = attr->cap.max_send_sge;
+ qp->rq.max_gs = attr->cap.max_recv_sge;
+ qp->max_inline_data = attr->cap.max_inline_data;
return &qp->ibv_qp;