[ofa-general] [PATCH] IB/mthca: recv poll cq optimization

Michael S. Tsirkin mst at mellanox.co.il
Wed Feb 28 13:02:35 PST 2007


All good recv work requests generate HW completions in FIFO order, so we can use
rq->tail rather than hardware data. In this way, we save a branch on data path
for recv completions (branch is still there for send completions).

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

---

Roland, what do you think? This increases the overall code size but I think the
extra code is on the error CQE handling path.  BTW, since most kernel QPs seem
not to use selective signaling, it might be worth it to optimize send
completions in a similiar way in case selective singaling is disabled on QP.

diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index efd79ef..78f8069 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -542,38 +542,37 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
 			     >> wq->wqe_shift);
 		entry->wr_id = (*cur_qp)->wrid[wqe_index +
 					       (*cur_qp)->rq.max];
+		if (wq->last_comp < wqe_index)
+			wq->tail += wqe_index - wq->last_comp;
+		else
+			wq->tail += wqe_index + wq->max - wq->last_comp;
+
+		wq->last_comp = wqe_index;
 	} else if ((*cur_qp)->ibqp.srq) {
 		struct mthca_srq *srq = to_msrq((*cur_qp)->ibqp.srq);
 		u32 wqe = be32_to_cpu(cqe->wqe);
-		wq = NULL;
 		wqe_index = wqe >> srq->wqe_shift;
 		entry->wr_id = srq->wrid[wqe_index];
 		mthca_free_srq_wqe(srq, wqe);
 	} else {
-		s32 wqe;
 		wq = &(*cur_qp)->rq;
-		wqe = be32_to_cpu(cqe->wqe);
-		wqe_index = wqe >> wq->wqe_shift;
-		/*
-		 * WQE addr == base - 1 might be reported in receive completion
-		 * with error instead of (rq size - 1) by Sinai FW 1.0.800 and
-		 * Arbel FW 5.1.400.  This bug should be fixed in later FW revs.
-		 */
-		if (unlikely(wqe_index < 0))
-			wqe_index = wq->max - 1;
-		entry->wr_id = (*cur_qp)->wrid[wqe_index];
+		wq->last_comp = wq->tail++ & (wq->max - 1);
+		entry->wr_id = (*cur_qp)->wrid[wq->last_comp];
 	}
 
-	if (wq) {
-		if (wq->last_comp < wqe_index)
-			wq->tail += wqe_index - wq->last_comp;
-		else
-			wq->tail += wqe_index + wq->max - wq->last_comp;
-
-		wq->last_comp = wqe_index;
-	}
+	if (unlikely(is_error)) {
+		if (!is_send && !(*cur_qp)->ibqp.srq) {
+			s32 wqe = be32_to_cpu(cqe->wqe);
+			wqe_index = wqe >> wq->wqe_shift;
+			/*
+			 * WQE addr == base - 1 might be reported in receive completion
+			 * with error instead of (rq size - 1) by Sinai FW 1.0.800 and
+			 * Arbel FW 5.1.400.  This bug should be fixed in later FW revs.
+			 */
+			if (unlikely(wqe_index < 0))
+				wqe_index = wq->max - 1;
+		}
 
-	if (is_error) {
 		handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
 				 (struct mthca_err_cqe *) cqe,
 				 entry, &free_cqe);
-- 
MST




More information about the general mailing list