On Fri, Nov 13, 2015 at 10:18:51AM -0500, Sonic wrote: > On Wed, Nov 11, 2015 at 9:20 AM, Gregor Best <g...@unobtanium.de> 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);