diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-10-03 13:10:16 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-10-03 13:10:16 +0000 |
commit | 711da383b644a291719613218b8c0dbc0033a2d4 (patch) | |
tree | a9d503cdffbbe284fdc1b7190d2210c81700f06d /sys | |
parent | c0b6e6aed00d90cda06809ae769d1cd15289219d (diff) |
in rxeof, instead of taking the biglock on every packet to call bpf
and ether_input, queue all the mbufs onto an mbuf_list on the stack
and then take the biglock once outside the loop.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_myx.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c index 2cfc3f8e45c..0464db49a5c 100644 --- a/sys/dev/pci/if_myx.c +++ b/sys/dev/pci/if_myx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_myx.c,v 1.67 2014/10/03 09:52:01 dlg Exp $ */ +/* $OpenBSD: if_myx.c,v 1.68 2014/10/03 13:10:15 dlg Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -1796,6 +1796,7 @@ myx_rxeof(struct myx_softc *sc) { static const struct myx_intrq_desc zerodesc = { 0, 0 }; struct ifnet *ifp = &sc->sc_ac.ac_if; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); struct myx_buf *mb; struct mbuf *m; int ring; @@ -1830,15 +1831,7 @@ myx_rxeof(struct myx_softc *sc) m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; - KERNEL_LOCK(); -#if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); -#endif - - ether_input_mbuf(ifp, m); - KERNEL_UNLOCK(); - ifp->if_ipackets++; + ml_enqueue(&ml, m); myx_buf_put(&sc->sc_rx_buf_free[ring], mb); @@ -1859,6 +1852,20 @@ myx_rxeof(struct myx_softc *sc) SET(rings, 1 << ring); } + ifp->if_ipackets += ml_len(&ml); + + KERNEL_LOCK(); +#if NBPFILTER > 0 + if (ifp->if_bpf) { + MBUF_LIST_FOREACH(&ml, m) + bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); + } +#endif + + while ((m = ml_dequeue(&ml)) != NULL) + ether_input_mbuf(ifp, m); + KERNEL_UNLOCK(); + return (rings); } |