6855964 e1000g driver corrupting LSO packets causes chipset hang and significant performance regression
authorchangqing li - Sun Microsystems - Beijing China <Changqing.Li@Sun.COM>
Mon, 21 Sep 2009 23:17:43 +0800
changeset 10589 7b05736960d1
parent 10588 dc03f981ea18
child 10590 43ff5881adbb
6855964 e1000g driver corrupting LSO packets causes chipset hang and significant performance regression 6681751 e1000g minor_perm inconsistent between package postinstall script and default minor_perm file
usr/src/pkgdefs/SUNWintgige/postinstall
usr/src/uts/common/io/e1000g/README
usr/src/uts/common/io/e1000g/e1000g_main.c
usr/src/uts/common/io/e1000g/e1000g_tx.c
--- a/usr/src/pkgdefs/SUNWintgige/postinstall	Mon Sep 21 08:55:28 2009 -0600
+++ b/usr/src/pkgdefs/SUNWintgige/postinstall	Mon Sep 21 23:17:43 2009 +0800
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -252,4 +252,4 @@
 	"pciex8086,10e5"
 	"pciex8086,10f5"
 	"pciex8086,294c"' \
-	-m '* 0666 root root' e1000g
+	-m '* 0666 root sys' e1000g
--- a/usr/src/uts/common/io/e1000g/README	Mon Sep 21 08:55:28 2009 -0600
+++ b/usr/src/uts/common/io/e1000g/README	Mon Sep 21 23:17:43 2009 +0800
@@ -688,3 +688,8 @@
    This version has the following fix:
     6846262 T2000 fma shows fault.io.pciex.device-interr in snv_115
     6870404 e1000g_reset can call e1000g_start after releasing dma resources
+
+5.3.13
+  This version has the following fixes:
+   6681751 e1000g minor_perm inconsistent between package postinstall script and default minor_perm file
+   6855964 e1000g driver corrupting LSO packets causes chipset hang and significant performance regression
--- a/usr/src/uts/common/io/e1000g/e1000g_main.c	Mon Sep 21 08:55:28 2009 -0600
+++ b/usr/src/uts/common/io/e1000g/e1000g_main.c	Mon Sep 21 23:17:43 2009 +0800
@@ -46,7 +46,7 @@
 
 static char ident[] = "Intel PRO/1000 Ethernet";
 static char e1000g_string[] = "Intel(R) PRO/1000 Network Connection";
-static char e1000g_version[] = "Driver Ver. 5.3.12";
+static char e1000g_version[] = "Driver Ver. 5.3.13";
 
 /*
  * Proto types for DDI entry points
--- a/usr/src/uts/common/io/e1000g/e1000g_tx.c	Mon Sep 21 08:55:28 2009 -0600
+++ b/usr/src/uts/common/io/e1000g/e1000g_tx.c	Mon Sep 21 23:17:43 2009 +0800
@@ -167,6 +167,7 @@
 	mblk_t *tmp;
 	mblk_t *new_mp;
 	mblk_t *pre_mp;
+	mblk_t *next_mp;
 	e1000g_tx_ring_t *tx_ring;
 	context_data_t cur_context;
 
@@ -234,6 +235,7 @@
 	/* Initialize variables */
 	desc_count = 1;	/* The initial value should be greater than 0 */
 	desc_total = 0;
+	new_mp = NULL;
 	QUEUE_INIT_LIST(&pending_list);
 
 	/* Process each mblk fragment and fill tx descriptors */
@@ -246,12 +248,12 @@
 		/* find the last fragment of the header */
 		len = MBLKL(mp);
 		ASSERT(len > 0);
-		nmp = mp;
+		next_mp = mp;
 		pre_mp = NULL;
 		while (len < cur_context.hdr_len) {
-			pre_mp = nmp;
-			nmp = nmp->b_cont;
-			len += MBLKL(nmp);
+			pre_mp = next_mp;
+			next_mp = next_mp->b_cont;
+			len += MBLKL(next_mp);
 		}
 		/*
 		 * If the header and the payload are in different mblks,
@@ -261,7 +263,7 @@
 		if (len == cur_context.hdr_len)
 			goto adjust_threshold;
 
-		hdr_frag_len = cur_context.hdr_len - (len - MBLKL(nmp));
+		hdr_frag_len = cur_context.hdr_len - (len - MBLKL(next_mp));
 		/*
 		 * There are two cases we need to reallocate a mblk for the
 		 * last header fragment:
@@ -270,8 +272,8 @@
 		 * 2. the header is in a single mblk shared with the payload
 		 * and the header is physical memory non-contiguous
 		 */
-		if ((nmp != mp) ||
-		    (P2NPHASE((uintptr_t)nmp->b_rptr, Adapter->sys_page_sz)
+		if ((next_mp != mp) ||
+		    (P2NPHASE((uintptr_t)next_mp->b_rptr, Adapter->sys_page_sz)
 		    < cur_context.hdr_len)) {
 			E1000G_DEBUG_STAT(tx_ring->stat_lso_header_fail);
 			/*
@@ -282,16 +284,16 @@
 			new_mp = allocb(hdr_frag_len, NULL);
 			if (!new_mp)
 				return (B_FALSE);
-			bcopy(nmp->b_rptr, new_mp->b_rptr, hdr_frag_len);
+			bcopy(next_mp->b_rptr, new_mp->b_rptr, hdr_frag_len);
 			/* link the new header fragment with the other parts */
 			new_mp->b_wptr = new_mp->b_rptr + hdr_frag_len;
-			new_mp->b_cont = nmp;
+			new_mp->b_cont = next_mp;
 			if (pre_mp)
 				pre_mp->b_cont = new_mp;
 			else
 				mp = new_mp;
-			nmp->b_rptr += hdr_frag_len;
-			frag_count ++;
+			next_mp->b_rptr += hdr_frag_len;
+			frag_count++;
 		}
 adjust_threshold:
 		/*
@@ -402,6 +404,17 @@
 	return (B_TRUE);
 
 tx_send_failed:
+	/* Restore mp to original */
+	if (new_mp) {
+		if (pre_mp) {
+			pre_mp->b_cont = next_mp;
+		}
+		new_mp->b_cont = NULL;
+		freemsg(new_mp);
+
+		next_mp->b_rptr -= hdr_frag_len;
+	}
+
 	/*
 	 * Enable Transmit interrupts, so that the interrupt routine can
 	 * call mac_tx_update() when transmit descriptors become available.