changeset 10633:62ff2de09191

6877975 TCP_corrupt exposes corruption from using LSO on hermon
author Rajkumar Sivaprakasam <Rajkumar.Sivaprakasam@Sun.COM>
date Wed, 23 Sep 2009 22:00:30 -0700
parents 704f6d4f41c9
children 6f69eed61369
files usr/src/uts/common/io/ib/adapters/hermon/hermon.c usr/src/uts/common/io/ib/adapters/hermon/hermon_wr.c usr/src/uts/common/io/ib/clients/ibd/ibd.c
diffstat 3 files changed, 17 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/ib/adapters/hermon/hermon.c	Wed Sep 23 20:55:51 2009 -0700
+++ b/usr/src/uts/common/io/ib/adapters/hermon/hermon.c	Wed Sep 23 22:00:30 2009 -0700
@@ -2377,8 +2377,9 @@
 	if (state->hs_devlim.log_max_gso_sz) {
 		hca_attr->hca_max_lso_size =
 		    (1 << state->hs_devlim.log_max_gso_sz);
-		/* More work needed in hermon_post_send for larger values */
-		hca_attr->hca_max_lso_hdr_size = 0x2c;	/* IPv4 only */
+		/* 64 = ctrl & datagram seg, 4 = LSO seg, 16 = 1 SGL */
+		hca_attr->hca_max_lso_hdr_size =
+		    state->hs_devlim.max_desc_sz_sq - (64 + 4 + 16);
 	}
 
 	caps |= IBT_HCA_WQE_SIZE_INFO;
--- a/usr/src/uts/common/io/ib/adapters/hermon/hermon_wr.c	Wed Sep 23 20:55:51 2009 -0700
+++ b/usr/src/uts/common/io/ib/adapters/hermon/hermon_wr.c	Wed Sep 23 22:00:30 2009 -0700
@@ -77,7 +77,7 @@
 	uint32_t			head, tail, next_tail, qsize_msk;
 	uint32_t			hdrmwqes;
 	uint32_t			nopcode, fence, immed_data = 0;
-	hermon_hw_wqe_sgl_t		*ds;
+	hermon_hw_wqe_sgl_t		*ds, *old_ds;
 	ibt_wr_ds_t			*sgl;
 	uint32_t			nds, dnds;
 	int				i, j, last_ds, num_ds, status;
@@ -142,9 +142,11 @@
 	 */
 	if (wr->wr_opcode == IBT_WRC_SEND_LSO) {
 		int total_len;
-		hermon_hw_wqe_sgl_t *old_ds;
 
 		nopcode = HERMON_WQE_SEND_NOPCODE_LSO;
+		if (wr->wr.ud_lso.lso_hdr_sz > 60) {
+			nopcode |= (1 << 6);	/* ReRead bit must be set */
+		}
 		dest = wr->wr.ud_lso.lso_ud_dest;
 		ah = (hermon_ahhdl_t)dest->ud_ah;
 		if (ah == NULL) {
@@ -159,21 +161,11 @@
 			status = IBT_QP_SGL_LEN_INVALID;
 			goto done;
 		}
-		bcopy(wr->wr.ud_lso.lso_hdr, (uint32_t *)ds + 1,
+		old_ds = ds;
+		bcopy(wr->wr.ud_lso.lso_hdr, (uint32_t *)old_ds + 1,
 		    wr->wr.ud_lso.lso_hdr_sz);
-		old_ds = ds;
 		ds = (hermon_hw_wqe_sgl_t *)((uintptr_t)ds + total_len);
-		for (i = 0; i < nds; i++) {
-			if (sgl[i].ds_len == 0)
-				continue;
-			HERMON_WQE_BUILD_DATA_SEG_SEND(&ds[num_ds], &sgl[i]);
-			num_ds++;
-			i++;
-			break;
-		}
-		membar_producer();
-		HERMON_WQE_BUILD_LSO(qp, old_ds, wr->wr.ud_lso.lso_mss,
-		    wr->wr.ud_lso.lso_hdr_sz);
+		i = 0;
 	} else if (wr->wr_opcode == IBT_WRC_SEND) {
 		if (wr->wr_flags & IBT_WR_SEND_IMMED) {
 			nopcode = HERMON_WQE_SEND_NOPCODE_SENDI;
@@ -217,6 +209,13 @@
 		HERMON_WQE_BUILD_DATA_SEG_SEND(&ds[last_ds], &sgl[j]);
 	}
 
+	membar_producer();
+
+	if (wr->wr_opcode == IBT_WRC_SEND_LSO) {
+		HERMON_WQE_BUILD_LSO(qp, old_ds, wr->wr.ud_lso.lso_mss,
+		    wr->wr.ud_lso.lso_hdr_sz);
+	}
+
 	fence = (wr->wr_flags & IBT_WR_SEND_FENCE) ? 1 : 0;
 
 	signaled_dbd = ((qp->qp_sq_sigtype == HERMON_QP_SQ_ALL_SIGNALED) ||
--- a/usr/src/uts/common/io/ib/clients/ibd/ibd.c	Wed Sep 23 20:55:51 2009 -0700
+++ b/usr/src/uts/common/io/ib/clients/ibd/ibd.c	Wed Sep 23 22:00:30 2009 -0700
@@ -135,7 +135,6 @@
 uint_t ibd_rx_softintr = 1;
 uint_t ibd_tx_softintr = 1;
 uint_t ibd_create_broadcast_group = 1;
-uint_t ibd_force_lso_disable = 1;
 #ifdef IBD_LOGGING
 uint_t ibd_log_sz = 0x20000;
 #endif
@@ -2309,16 +2308,6 @@
 		state->id_lso_policy = B_FALSE;
 	}
 
-	/*
-	 * Work-around for Bug 6866957. Ignore policy from ibd.conf.
-	 * Turn off LSO forcibly. Remove it when the work-around is no longer
-	 * needed.
-	 */
-	if (ibd_force_lso_disable) {
-		state->id_lso_policy = B_FALSE;
-	}
-	/* End of Workaround */
-
 	if (hca_attrs.hca_max_lso_size > 0) {
 		state->id_lso_capable = B_TRUE;
 		if (hca_attrs.hca_max_lso_size > IBD_LSO_MAXLEN)