Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Sep 2009 16:53:12 +0000 (UTC)
From:      Jack F Vogel <jfv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r197093 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/e1000 dev/xen/xenpci
Message-ID:  <200909111653.n8BGrCd3057722@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jfv
Date: Fri Sep 11 16:53:12 2009
New Revision: 197093
URL: http://svn.freebsd.org/changeset/base/197093

Log:
  This fixes kern/138516, an mbuf leak in both the em
  and igb driver, when a transmit fails the packet/mbuf
  was not being requeued. Thanks to those that pointed
  this problem out.
  
  Approved by:  re

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/if_em.c
  stable/8/sys/dev/e1000/if_igb.c
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/e1000/if_em.c
==============================================================================
--- stable/8/sys/dev/e1000/if_em.c	Fri Sep 11 15:38:27 2009	(r197092)
+++ stable/8/sys/dev/e1000/if_em.c	Fri Sep 11 16:53:12 2009	(r197093)
@@ -1034,9 +1034,10 @@ em_mq_start_locked(struct ifnet *ifp, st
 		return (error);
 	} else if (drbr_empty(ifp, adapter->br) &&
 	    (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
-		if (em_xmit(adapter, &m)) {
-			if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0)
-				return (error);
+		if ((error = em_xmit(adapter, &m)) != 0) {
+			if (m != NULL)
+				error = drbr_enqueue(ifp, adapter->br, m);
+			return (error);
 		} else {
 			/*
 			 * We've bypassed the buf ring so we need to update
@@ -1063,8 +1064,12 @@ process:
                 next = drbr_dequeue(ifp, adapter->br);
                 if (next == NULL)
                         break;
-                if (em_xmit(adapter, &next))
+                if ((error = em_xmit(adapter, &next)) != 0) {
+			if (next != NULL)
+				error = drbr_enqueue(ifp, adapter->br, next);
                         break;
+		}
+		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
                 ETHER_BPF_MTAP(ifp, next);
                 /* Set the watchdog */
                 adapter->watchdog_timer = EM_TX_TIMEOUT;
@@ -1073,7 +1078,7 @@ process:
         if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 
-	return (0);
+	return (error);
 }
 
 /*

Modified: stable/8/sys/dev/e1000/if_igb.c
==============================================================================
--- stable/8/sys/dev/e1000/if_igb.c	Fri Sep 11 15:38:27 2009	(r197092)
+++ stable/8/sys/dev/e1000/if_igb.c	Fri Sep 11 16:53:12 2009	(r197093)
@@ -854,9 +854,10 @@ igb_mq_start_locked(struct ifnet *ifp, s
 
 	/* If nothing queued go right to xmit */
 	if (drbr_empty(ifp, txr->br)) {
-		if (igb_xmit(txr, &m)) {
-			if (m && (err = drbr_enqueue(ifp, txr->br, m)) != 0)
-                                return (err);
+		if ((err = igb_xmit(txr, &m)) != 0) {
+			if (m != NULL)
+				err = drbr_enqueue(ifp, txr->br, m);
+			return (err);
 		} else {
 			/* Success, update stats */
 			drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
@@ -880,8 +881,12 @@ process:
 		next = drbr_dequeue(ifp, txr->br);
 		if (next == NULL)
 			break;
-		if (igb_xmit(txr, &next))
+		if ((err = igb_xmit(txr, &next)) != 0) {
+			if (next != NULL)
+				err = drbr_enqueue(ifp, txr->br, next);
 			break;
+		}
+		drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
 		ETHER_BPF_MTAP(ifp, next);
 		/* Set the watchdog */
 		txr->watchdog_timer = IGB_TX_TIMEOUT;
@@ -1531,8 +1536,11 @@ igb_update_aim(struct rx_ring *rxr)
 	if (olditr != newitr) {
 		/* Change interrupt rate */
 		rxr->eitr_setting = newitr;
-		E1000_WRITE_REG(&adapter->hw, E1000_EITR(rxr->me),
-		    newitr | (newitr << 16));
+		if (adapter->hw.mac.type == e1000_82575)
+			newitr |= newitr << 16;
+		else
+			newitr |= 0x8000000;
+		E1000_WRITE_REG(&adapter->hw, E1000_EITR(rxr->me), newitr);
 	}
 
 	rxr->bytes = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909111653.n8BGrCd3057722>