[ofa-general] [PATCH] mlx4_ib: fix for bugzilla 1383 (LSO packet processing)

Jack Morgenstein jackm at dev.mellanox.co.il
Mon Dec 29 02:23:11 PST 2008


mlx4_ib: fix for Bugzilla 1383 (LSO packet processing).

The LSO segment header in the WQE was written too early.

Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 39167a7..e931d88 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1462,7 +1462,7 @@ static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg)
 }
 
 static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
-			 struct mlx4_ib_qp *qp, unsigned *lso_seg_len)
+			 struct mlx4_ib_qp *qp, unsigned *lso_seg_len, __be32 *lso_hdr_sz)
 {
 	unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16);
 
@@ -1479,10 +1479,7 @@ static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
 
 	memcpy(wqe->header, wr->wr.ud.header, wr->wr.ud.hlen);
 
-	/* make sure LSO header is written before overwriting stamping */
-	wmb();
-
-	wqe->mss_hdr_size = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 |
+	*lso_hdr_sz = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 |
 					wr->wr.ud.hlen);
 
 	*lso_seg_len = halign;
@@ -1519,6 +1516,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	int uninitialized_var(size);
 	unsigned uninitialized_var(seglen);
 	int i;
+	__be32 *lso_wqe;
+	__be32 uninitialized_var(lso_hdr_sz);
 
 	spin_lock_irqsave(&qp->sq.lock, flags);
 
@@ -1606,13 +1605,21 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
 
 			if (wr->opcode == IB_WR_LSO) {
-				err = build_lso_seg(wqe, wr, qp, &seglen);
+				err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz);
 				if (unlikely(err)) {
 					*bad_wr = wr;
 					goto out;
 				}
+				lso_wqe = (__be32 *) wqe;
 				wqe  += seglen;
-				size += seglen / 16;
+				dseg = wqe;
+				dseg += wr->num_sge - 1;
+				size += (seglen / 16) + wr->num_sge *
+						(sizeof (struct mlx4_wqe_data_seg) / 16);
+				for (i = wr->num_sge - 1; i >= 0; --i, --dseg)
+					set_data_seg(dseg, wr->sg_list + i);
+				*lso_wqe = lso_hdr_sz;
+				goto lso_continue;
 			}
 			break;
 
@@ -1652,6 +1659,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 		for (i = wr->num_sge - 1; i >= 0; --i, --dseg)
 			set_data_seg(dseg, wr->sg_list + i);
 
+lso_continue:
 		ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
 				    MLX4_WQE_CTRL_FENCE : 0) | size;
 



More information about the general mailing list