em(4) appears to be susceptible to the same problem that if_bge.c
r1.355 addressed.

long mbuf chains can cause em_encap to fail, which will cause OACTIVE
to be set on the interface, and the problem packet to remain at the
start of the send queue. this will cause no packets to end up on
the tx ring, so em_txeof wont run which is where OACTIVE is cleared.

this diff makes em(4) defrag long mbuf chains.

i havent tested this, could someone give it a spin? or an ok?

Index: if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.280
diff -u -p -r1.280 if_em.c
--- if_em.c     11 Jun 2014 04:28:43 -0000      1.280
+++ if_em.c     4 Jul 2014 04:03:23 -0000
@@ -1133,10 +1133,21 @@ em_encap(struct em_softc *sc, struct mbu
        map = tx_buffer->map;
 
        error = bus_dmamap_load_mbuf(sc->txtag, map, m_head, BUS_DMA_NOWAIT);
-       if (error != 0) {
+       switch (error) {
+       case 0:
+               break;
+       case EFBIG:
+               if ((error = m_defrag(m_head, M_DONTWAIT)) == 0 &&
+                   (error = bus_dmamap_load_mbuf(sc->txtag, map, m_head,
+                    BUS_DMA_NOWAIT)) == 0)
+                       break;
+
+               /* FALLTHROUGH */
+       default:
                sc->no_tx_dma_setup++;
                goto loaderr;
        }
+
        EM_KASSERT(map->dm_nsegs!= 0, ("em_encap: empty packet"));
 
        if (map->dm_nsegs > sc->num_tx_desc_avail - 2)

Reply via email to