summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-07-07 23:12:01 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-07-07 23:12:01 +0000
commit5a1f8b249a3238800919b41a93303c1adf41bcfe (patch)
treeb6391838e0c2398ec0b7f1a00006ff2a4a8e6344 /sys/dev
parent0eaec9e69f942d1f7150392b86029c266106e548 (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.c15
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)