[ofa-general] [PATCH] IB/libmthca: Pre link receive WQEs in Tavor mode

Eli Cohen eli at mellanox.co.il
Thu Jan 24 06:27:11 PST 2008


Pre link receive WQEs in Tavor mode

Tavor mode requires that each WQE in a posted list of receive WQEs
will have a valid NDA field. This requirement holds true for regular QPs
as well as for SRQs. This patch prelinks the receive queue in a regular
QP and keeps the free list in SRQ always properly linked.

Signed-off-by: Eli Cohen <eli at mellanox.co.il>
Reviewed-by: Jack Morgenstein <jackm at mellanox.co.il>
---
 src/qp.c  |   14 ++++++++------
 src/srq.c |   24 +++++++++++++++---------
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/qp.c b/src/qp.c
index 841e316..3c5f049 100644
--- a/src/qp.c
+++ b/src/qp.c
@@ -360,7 +360,6 @@ int mthca_tavor_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
 		prev_wqe = qp->rq.last;
 		qp->rq.last = wqe;
 
-		((struct mthca_next_seg *) wqe)->nda_op = 0;
 		((struct mthca_next_seg *) wqe)->ee_nds =
 			htonl(MTHCA_NEXT_DBD);
 		((struct mthca_next_seg *) wqe)->flags =
@@ -388,9 +387,6 @@ int mthca_tavor_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
 
 		qp->wrid[ind + qp->sq.max] = wr->wr_id;
 
-		((struct mthca_next_seg *) prev_wqe)->nda_op =
-			htonl((ind << qp->rq.wqe_shift) | 1);
-		wmb();
 		((struct mthca_next_seg *) prev_wqe)->ee_nds =
 			htonl(MTHCA_NEXT_DBD | size);
 
@@ -786,6 +782,8 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
 {
 	int size;
 	int max_sq_sge;
+	struct mthca_next_seg *next;
+	int i;
 
 	qp->rq.max_gs 	 = cap->max_recv_sge;
 	qp->sq.max_gs 	 = cap->max_send_sge;
@@ -860,9 +858,7 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
 	memset(qp->buf.buf, 0, qp->buf_size);
 
 	if (mthca_is_memfree(pd->context)) {
-		struct mthca_next_seg *next;
 		struct mthca_data_seg *scatter;
-		int i;
 		uint32_t sz;
 
 		sz = htonl((sizeof (struct mthca_next_seg) +
@@ -886,6 +882,12 @@ int mthca_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap,
 					      qp->sq.wqe_shift) +
 					     qp->send_wqe_offset);
 		}
+	} else {
+		for (i = 0; i < qp->rq.max; ++i) {
+			next = get_recv_wqe(qp, i);
+			next->nda_op = htonl((((i + 1) % qp->rq.max) <<
+					     qp->rq.wqe_shift) | 1);
+		}
 	}
 
 	qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
diff --git a/src/srq.c b/src/srq.c
index 72b7a0e..1d326b8 100644
--- a/src/srq.c
+++ b/src/srq.c
@@ -64,9 +64,13 @@ static inline int *wqe_to_link(void *wqe)
 
 void mthca_free_srq_wqe(struct mthca_srq *srq, int ind)
 {
+	struct mthca_next_seg *last_free;
+
 	pthread_spin_lock(&srq->lock);
 
-	*wqe_to_link(get_wqe(srq, srq->last_free)) = ind;
+	last_free = get_wqe(srq, srq->last_free);
+	*wqe_to_link(last_free) = ind;
+	last_free->nda_op = htonl((ind << srq->wqe_shift) | 1);
 	*wqe_to_link(get_wqe(srq, ind)) = -1;
 	srq->last_free = ind;
 
@@ -113,7 +117,6 @@ int mthca_tavor_post_srq_recv(struct ibv_srq *ibsrq,
 		prev_wqe  = srq->last;
 		srq->last = wqe;
 
-		((struct mthca_next_seg *) wqe)->nda_op = 0;
 		((struct mthca_next_seg *) wqe)->ee_nds = 0;
 		/* flags field will always remain 0 */
 
@@ -142,9 +145,6 @@ int mthca_tavor_post_srq_recv(struct ibv_srq *ibsrq,
 			((struct mthca_data_seg *) wqe)->addr = 0;
 		}
 
-		((struct mthca_next_seg *) prev_wqe)->nda_op =
-			htonl((ind << srq->wqe_shift) | 1);
-		wmb();
 		((struct mthca_next_seg *) prev_wqe)->ee_nds =
 			htonl(MTHCA_NEXT_DBD);
 
@@ -218,8 +218,6 @@ int mthca_arbel_post_srq_recv(struct ibv_srq *ibsrq,
 			break;
 		}
 
-		((struct mthca_next_seg *) wqe)->nda_op =
-			htonl((next_ind << srq->wqe_shift) | 1);
 		((struct mthca_next_seg *) wqe)->ee_nds = 0;
 		/* flags field will always remain 0 */
 
@@ -302,9 +300,17 @@ int mthca_alloc_srq_buf(struct ibv_pd *pd, struct ibv_srq_attr *attr,
 	 */
 
 	for (i = 0; i < srq->max; ++i) {
-		wqe = get_wqe(srq, i);
+		struct mthca_next_seg *next;
 
-		*wqe_to_link(wqe) = i < srq->max - 1 ? i + 1 : -1;
+		next = wqe = get_wqe(srq, i);
+
+		if (i < srq->max - 1) {
+			*wqe_to_link(wqe) = i + 1;
+			next->nda_op = htonl(((i + 1) << srq->wqe_shift) | 1);
+		} else {
+			*wqe_to_link(wqe) = -1;
+			next->nda_op = 0;
+		}
 
 		for (scatter = wqe + sizeof (struct mthca_next_seg);
 		     (void *) scatter < wqe + (1 << srq->wqe_shift);
-- 
1.5.3.8





More information about the general mailing list