On Fri, Nov 13, 2015 at 10:18:51AM -0500, Sonic wrote:
> On Wed, Nov 11, 2015 at 9:20 AM, Gregor Best <[email protected]> wrote:
> > I've done some further testing and I think I've narrowed it down to the
> > "Unlocking em(4) a bit further"-patch [0].
could you try this? its not written with the wdog stuff in mind,
but it does touch that stuff so it might help.
Index: if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.310
diff -u -p -r1.310 if_em.c
--- if_em.c 29 Oct 2015 03:19:42 -0000 1.310
+++ if_em.c 15 Nov 2015 14:01:39 -0000
@@ -605,16 +605,20 @@ em_start(struct ifnet *ifp)
}
for (;;) {
- IFQ_POLL(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
- if (em_encap(sc, m_head)) {
+ if (sc->num_tx_desc_avail < EM_MAX_SCATTER + 2) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
+ break;
+
+ if (em_encap(sc, m_head)) {
+ m_freem(m_head);
+ ifp->if_oerrors++;
+ continue;
+ }
#if NBPFILTER > 0
/* Send a copy of the frame to the BPF listener */
@@ -622,9 +626,6 @@ em_start(struct ifnet *ifp)
bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
#endif
- /* Set timeout in case hardware has problems transmitting */
- ifp->if_timer = EM_TX_TIMEOUT;
-
post = 1;
}
@@ -637,8 +638,11 @@ em_start(struct ifnet *ifp)
* this tells the E1000 that this frame is
* available to transmit.
*/
- if (post)
+ if (post) {
E1000_WRITE_REG(&sc->hw, TDT, sc->next_avail_tx_desc);
+
+ ifp->if_timer = EM_TX_TIMEOUT;
+ }
}
}
@@ -1104,12 +1108,6 @@ em_encap(struct em_softc *sc, struct mbu
struct em_buffer *tx_buffer, *tx_buffer_mapped;
struct em_tx_desc *current_tx_desc = NULL;
- /* Check that we have least the minimal number of TX descriptors. */
- if (sc->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
- sc->no_tx_desc_avail1++;
- return (ENOBUFS);
- }
-
if (sc->hw.mac_type == em_82547) {
bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
sc->txdma.dma_map->dm_mapsize,
@@ -1147,9 +1145,6 @@ em_encap(struct em_softc *sc, struct mbu
EM_KASSERT(map->dm_nsegs!= 0, ("em_encap: empty packet"));
- if (map->dm_nsegs > sc->num_tx_desc_avail - 2)
- goto fail;
-
if (sc->hw.mac_type >= em_82543 && sc->hw.mac_type != em_82575 &&
sc->hw.mac_type != em_82580 && sc->hw.mac_type != em_i210 &&
sc->hw.mac_type != em_i350)
@@ -1168,9 +1163,9 @@ em_encap(struct em_softc *sc, struct mbu
* Check the Address and Length combination and
* split the data accordingly
*/
- array_elements =
em_fill_descriptors(map->dm_segs[j].ds_addr,
-
map->dm_segs[j].ds_len,
- &desc_array);
+ array_elements = em_fill_descriptors(
+ map->dm_segs[j].ds_addr,
+ map->dm_segs[j].ds_len, &desc_array);
for (counter = 0; counter < array_elements; counter++) {
if (txd_used == sc->num_tx_desc_avail) {
sc->next_avail_tx_desc = txd_saved;
@@ -2481,8 +2476,7 @@ em_txeof(struct em_softc *sc)
* If we have enough room, clear IFF_OACTIVE to tell the stack
* that it is OK to send packets.
*/
- if (ISSET(ifp->if_flags, IFF_OACTIVE) &&
- num_avail > EM_TX_OP_THRESHOLD) {
+ if (num_avail > 0 && ISSET(ifp->if_flags, IFF_OACTIVE)) {
KERNEL_LOCK();
CLR(ifp->if_flags, IFF_OACTIVE);
em_start(ifp);