Date: Mon, 27 Apr 2009 17:22:15 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191566 - head/sys/dev/e1000 Message-ID: <200904271722.n3RHMF53020951@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904271722.n3RHMF53020951>