svn commit: r191566 - head/sys/dev/e1000

Jack F Vogel jfv at FreeBSD.org
Mon Apr 27 17:22:16 UTC 2009


Author: jfv
Date: Mon Apr 27 17:22:14 2009
New Revision: 191566
URL: http://svn.freebsd.org/changeset/base/191566

Log:
  Thanks for Michael Tuexen for tracking down a path where
  the watchdog timer was not being rearmed in txeof, and also
  a missing case in the new code.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/e1000/if_em.c

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c	Mon Apr 27 16:57:19 2009	(r191565)
+++ head/sys/dev/e1000/if_em.c	Mon Apr 27 17:22:14 2009	(r191566)
@@ -1013,12 +1013,15 @@ em_transmit_locked(struct ifnet *ifp, st
 	if (ADAPTER_RING_EMPTY(adapter) &&
 	    (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) {
 		if (em_xmit(adapter, &m)) {
-			if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0) {
+			if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0)
 				return (error);
-			}
-		} else{
-			/* Send a copy of the frame to the BPF listener */
+		} else {
+			/*
+			** Send a copy of the frame to the BPF
+			** listener and set the watchdog on.
+			*/
 			ETHER_BPF_MTAP(ifp, m);
+			addapter->watchdog_timer = EM_TX_TIMEOUT;
 		}
 	} else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0)
 		return (error);
@@ -1086,6 +1089,8 @@ em_start_locked(struct ifnet *ifp)
 		if (em_xmit(adapter, &m_head)) {
 			if (m_head == NULL)
 				break;
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 			break;
 		}
 
@@ -4029,6 +4034,7 @@ static void
 em_txeof(struct adapter *adapter)
 {
         int first, last, done, num_avail;
+	u32 cleaned = 0;
         struct em_buffer *tx_buffer;
         struct e1000_tx_desc   *tx_desc, *eop_desc;
 	struct ifnet   *ifp = adapter->ifp;
@@ -4064,7 +4070,7 @@ em_txeof(struct adapter *adapter)
                 	tx_desc->upper.data = 0;
                 	tx_desc->lower.data = 0;
                 	tx_desc->buffer_addr = 0;
-                	num_avail++;
+                	++num_avail; ++cleaned;
 
 			if (tx_buffer->m_head) {
 				ifp->if_opackets++;
@@ -4101,21 +4107,22 @@ em_txeof(struct adapter *adapter)
         adapter->next_tx_to_clean = first;
 
         /*
-         * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack
-         * that it is OK to send packets.
-         * If there are no pending descriptors, clear the timeout. Otherwise,
-         * if some descriptors have been freed, restart the timeout.
+         * If we have enough room, clear IFF_DRV_OACTIVE to
+         * tell the stack that it is OK to send packets.
+         * If there are no pending descriptors, clear the timeout.
          */
         if (num_avail > EM_TX_CLEANUP_THRESHOLD) {                
                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		/* All clean, turn off the timer */
                 if (num_avail == adapter->num_tx_desc) {
 			adapter->watchdog_timer = 0;
-		} else
-		/* Some cleaned, reset the timer */
-                if (num_avail != adapter->num_tx_desc_avail)
-			adapter->watchdog_timer = EM_TX_TIMEOUT;
+        		adapter->num_tx_desc_avail = num_avail;
+			return;
+		} 
         }
+
+	/* If any descriptors cleaned, reset the watchdog */
+	if (cleaned)
+		adapter->watchdog_timer = EM_TX_TIMEOUT;
         adapter->num_tx_desc_avail = num_avail;
 	return;
 }


More information about the svn-src-head mailing list