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);

Reply via email to