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 <[email protected]>

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;
 
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to