diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-07 23:12:01 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-07 23:12:01 +0000 |
commit | 5a1f8b249a3238800919b41a93303c1adf41bcfe (patch) | |
tree | b6391838e0c2398ec0b7f1a00006ff2a4a8e6344 /sys/dev | |
parent | 0eaec9e69f942d1f7150392b86029c266106e548 (diff) |
if em encounters a heavilty fragmented packet, it can (will) stall the
entire tx path. if we try to bus_dmamap_load a very fragmented packet
m_defrag it and try again.
this is just like if_bge.c r1.355.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_em.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index d60a2386aaf..ceb3720ac78 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/* $OpenBSD: if_em.c,v 1.280 2014/06/11 04:28:43 dlg Exp $ */ +/* $OpenBSD: if_em.c,v 1.281 2014/07/07 23:12:00 dlg Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -1133,10 +1133,21 @@ em_encap(struct em_softc *sc, struct mbuf *m_head) 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) |