summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/Makefile7
-rw-r--r--share/man/man9/ifq_enq.9140
-rw-r--r--sys/arch/armv7/imx/imxenet.c7
-rw-r--r--sys/arch/armv7/sunxi/sxie.c8
-rw-r--r--sys/arch/sgi/dev/if_iec.c10
-rw-r--r--sys/arch/sgi/dev/if_mec.c7
-rw-r--r--sys/arch/sgi/hpc/if_sq.c10
-rw-r--r--sys/arch/socppc/dev/if_tsec.c9
-rw-r--r--sys/arch/sparc64/dev/vnet.c14
-rw-r--r--sys/arch/vax/if/if_qe.c7
-rw-r--r--sys/dev/ic/aic6915.c9
-rw-r--r--sys/dev/ic/an.c7
-rw-r--r--sys/dev/ic/dc.c11
-rw-r--r--sys/dev/ic/elink3.c9
-rw-r--r--sys/dev/ic/fxp.c12
-rw-r--r--sys/dev/ic/gem.c9
-rw-r--r--sys/dev/ic/hme.c9
-rw-r--r--sys/dev/ic/lemac.c8
-rw-r--r--sys/dev/ic/pgt.c22
-rw-r--r--sys/dev/ic/re.c10
-rw-r--r--sys/dev/ic/rt2560.c7
-rw-r--r--sys/dev/ic/rt2661.c7
-rw-r--r--sys/dev/ic/rtw.c7
-rw-r--r--sys/dev/ic/smc83c170.c15
-rw-r--r--sys/dev/ic/smc91cxx.c9
-rw-r--r--sys/dev/ic/ti.c7
-rw-r--r--sys/dev/isa/if_ef_isapnp.c9
-rw-r--r--sys/dev/isa/if_ex.c7
-rw-r--r--sys/dev/pci/if_bce.c7
-rw-r--r--sys/dev/pci/if_bnx.c7
-rw-r--r--sys/dev/pci/if_cas.c7
-rw-r--r--sys/dev/pci/if_de.c93
-rw-r--r--sys/dev/pci/if_em.c7
-rw-r--r--sys/dev/pci/if_ipw.c11
-rw-r--r--sys/dev/pci/if_iwi.c12
-rw-r--r--sys/dev/pci/if_ix.c7
-rw-r--r--sys/dev/pci/if_ixgb.c7
-rw-r--r--sys/dev/pci/if_lge.c7
-rw-r--r--sys/dev/pci/if_lii.c7
-rw-r--r--sys/dev/pci/if_msk.c7
-rw-r--r--sys/dev/pci/if_nep.c7
-rw-r--r--sys/dev/pci/if_nfe.c7
-rw-r--r--sys/dev/pci/if_nge.c7
-rw-r--r--sys/dev/pci/if_nxe.c7
-rw-r--r--sys/dev/pci/if_pcn.c20
-rw-r--r--sys/dev/pci/if_se.c7
-rw-r--r--sys/dev/pci/if_sis.c7
-rw-r--r--sys/dev/pci/if_sk.c7
-rw-r--r--sys/dev/pci/if_stge.c13
-rw-r--r--sys/dev/pci/if_tht.c7
-rw-r--r--sys/dev/pci/if_txp.c9
-rw-r--r--sys/dev/pci/if_vic.c8
-rw-r--r--sys/dev/pci/if_vio.c10
-rw-r--r--sys/dev/pci/if_xge.c11
-rw-r--r--sys/dev/pcmcia/if_malo.c3
-rw-r--r--sys/dev/pcmcia/if_xe.c7
-rw-r--r--sys/dev/usb/if_aue.c7
-rw-r--r--sys/dev/usb/if_axe.c7
-rw-r--r--sys/dev/usb/if_axen.c7
-rw-r--r--sys/dev/usb/if_cdce.c7
-rw-r--r--sys/dev/usb/if_cdcef.c9
-rw-r--r--sys/dev/usb/if_cue.c7
-rw-r--r--sys/dev/usb/if_kue.c7
-rw-r--r--sys/dev/usb/if_mos.c7
-rw-r--r--sys/dev/usb/if_smsc.c7
-rw-r--r--sys/dev/usb/if_udav.c7
-rw-r--r--sys/dev/usb/if_ugl.c7
-rw-r--r--sys/dev/usb/if_upl.c7
-rw-r--r--sys/dev/usb/if_url.c7
-rw-r--r--sys/dev/usb/if_urndis.c7
-rw-r--r--sys/net/hfsc.c327
-rw-r--r--sys/net/hfsc.h19
-rw-r--r--sys/net/if.c334
-rw-r--r--sys/net/if_tun.c46
-rw-r--r--sys/net/if_var.h167
-rw-r--r--sys/net/pf_if.c7
-rw-r--r--sys/net/pf_ioctl.c167
-rw-r--r--sys/net/pfvar.h5
-rw-r--r--sys/sys/mbuf.h32
79 files changed, 1224 insertions, 689 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 386f4bc65ce..ddffd6be35c 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.253 2015/11/15 19:35:05 jmc Exp $
+# $OpenBSD: Makefile,v 1.254 2015/11/20 03:35:22 dlg Exp $
# $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $
# Makefile for section 9 (kernel function and variable) manual pages.
@@ -18,7 +18,7 @@ MAN= aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \
ieee80211.9 ieee80211_crypto.9 ieee80211_input.9 ieee80211_ioctl.9 \
ieee80211_node.9 ieee80211_output.9 ieee80211_proto.9 \
ieee80211_radiotap.9 \
- if_rxr_init.9 iic.9 intro.9 inittodr.9 intr_barrier.9 \
+ if_rxr_init.9 ifq_enq.9 iic.9 intro.9 inittodr.9 intr_barrier.9 \
kern.9 km_alloc.9 knote.9 kthread.9 ktrace.9 \
loadfirmware.9 lock.9 log.9 \
malloc.9 membar_sync.9 mbuf.9 mbuf_tags.9 md5.9 mi_switch.9 \
@@ -216,6 +216,9 @@ MLINKS+=ieee80211_proto.9 ieee80211_proto_attach.9 \
MLINKS+=if_rxr_init.9 if_rxr_get.9 if_rxr_init.9 if_rxr_put.9 \
if_rxr_init.9 if_rxr_inuse.9 if_rxr_init.9 if_rxr_ioctl.9 \
if_rxr_init.9 if_rxr_info_ioctl.9
+MLINKS+=ifq_enq.9 ifq_deq.9 ifq_enq.9 ifq_deq_begin.9 \
+ ifq_enq.9 ifq_deq_commit.9 ifq_enq.9 ifq_deq_rollback.9 \
+ ifq_enq.9 ifq_purge.9 ifq_enq.9 ifq_len.9 ifq_enq.9 ifq_empty.9
MLINKS+=iic.9 iic_acquire_bus.9 iic.9 iic_release_bus.9 iic.9 iic_exec.9 \
iic.9 iic_smbus_write_byte.9 iic.9 iic_smbus_read_byte.9 \
iic.9 iic_smbus_receive_byte.9
diff --git a/share/man/man9/ifq_enq.9 b/share/man/man9/ifq_enq.9
new file mode 100644
index 00000000000..a4be8a0aceb
--- /dev/null
+++ b/share/man/man9/ifq_enq.9
@@ -0,0 +1,140 @@
+.\" $OpenBSD: ifq_enq.9,v 1.1 2015/11/20 03:35:22 dlg Exp $
+.\"
+.\" Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: November 20 2015 $
+.Dt IFQ_ENQ 9
+.Os
+.Sh NAME
+.Nm ifq_enq ,
+.Nm ifq_deq ,
+.Nm ifq_deq_begin ,
+.Nm ifq_deq_commit ,
+.Nm ifq_deq_rollback ,
+.Nm ifq_purge ,
+.Nm ifq_len ,
+.Nm ifq_empty
+.Nd Interface send queue API
+.Sh SYNOPSIS
+.In net/if_var.h
+.Ft int
+.Fn ifq_enq "struct ifqueue *ifq" "struct mbuf *m"
+.Ft struft mbuf *
+.Fn ifq_deq "struct ifqueue *ifq"
+.Ft struft mbuf *
+.Fn ifq_deq_begin "struct ifqueue *ifq"
+.Ft void
+.Fn ifq_deq_commit "struct ifqueue *ifq" "struct mbuf *m"
+.Ft void
+.Fn ifq_deq_rollback "struct ifqueue *ifq" "struct mbuf *m"
+.Ft unsigned int
+.Fn ifq_purge "struct ifqueue *ifq"
+.Ft unsigned int
+.Fn ifq_len "struct ifqueue *ifq"
+.Ft unsigned int
+.Fn ifq_empty "struct ifqueue *ifq"
+.Sh DESCRIPTION
+The ifqueue API provides implementions of data structures and
+operations for the network stack to queue mbufs for a network driver
+to dequeue from its start routine for transmission.
+.Bl -tag -width Ds
+.It Fn ifq_enq "struct ifqueue *ifq" "struct mbuf *m"
+Enqueue mbuf
+.Fa m
+on the
+.Fa ifq
+interface send queue.
+If the queue rejects the packet it will be freed with
+.Xr m_freem 9
+and counted as a drop.
+.It Fn ifq_deq "struct ifqueue *ifq"
+Dequeue the next mbuf to be transmitted from the
+.Fa ifq
+interface send queue.
+.It Fn ifq_deq_begin "struct ifqueue *ifq"
+Get a reference to the next mbuf to be transmitted from the
+.Fa ifq
+interface send queue.
+If an mbuf is to be transmitted, also acquire a lock on the send queue
+to exclude modification or freeing of the referenced mbuf.
+The mbuf must not be freed, or have its length (m_pkthdr.len) or
+cookie (m_pkthdr.ph_cookie) modified until it has been dequeued
+completely with
+.Fn ifq_deq_commit .
+.It Fn ifq_deq_commit "struct ifqueue *ifq" "struct mbuf *m"
+Dequeue the mbuf
+.Fa m
+that was referenced by a previous call to
+.Fn ifq_deq_begin
+and release the lock on
+.Fa ifq .
+.It Fn ifq_deq_rollback "struct ifqueue *ifq" "struct mbuf *m"
+Release the lock on the interface send queue
+.Fa ifq
+that was acquired while a reference to
+.Fa m
+was being held.
+.It Fn ifq_purge "struct ifqueue *ifq"
+Free all the mbufs on the interface send queue
+.Fa ifq .
+Freed mbufs will be accounted as drops.
+.It Fn ifq_len "struct ifqueue *ifq"
+Return the number of mbufs on the interface send queue
+.Fa ifq .
+Note that while
+.Fn ifq_len
+may report that mbufs are on the queue, the current queue
+discipline may not make them available for dequeueing with
+.Fn ifq_deq
+or
+.Fn ifq_deq_begin .
+.It Fn ifq_empty "struct ifqueue *ifq"
+Return if the interface send queue
+.Fa ifq
+is empty.
+.El
+.Sh CONTEXT
+.Fn ifq_enq ,
+.Fn ifq_deq ,
+.Fn ifq_deq_begin ,
+.Fn ifq_deq_commit ,
+.Fn ifq_deq_rollback ,
+.Fn ifq_purge ,
+.Fn ifq_len ,
+and
+.Fn ifq_empty
+can be called during autoconf, from process context, or from interrupt context.
+.Sh RETURN VALUES
+.Fn ifq_enq
+returns 0 if the mbuf was successfully queued, or non-zero if mbuf was freed.
+.Pp
+.Fn ifq_deq
+and
+.Fn ifq_deq_begin
+return the next mbuf to be transmitted by the interface.
+If no packet is available for transmission,
+.Dv NULL
+is returned.
+.Pp
+.Fn ifq_purge
+returns the number of mbufs that were removed from the queue and freed.
+.Pp
+.Fn ifq_len
+returns the number of mbufs on the queue.
+.Pp
+.Fn ifq_empty
+returns a non-zero value if the queue is empty, otherwise 0.
+.Sh SEE ALSO
+.Xr m_freem 9
diff --git a/sys/arch/armv7/imx/imxenet.c b/sys/arch/armv7/imx/imxenet.c
index eb6a39ec6ba..e6067b5d03c 100644
--- a/sys/arch/armv7/imx/imxenet.c
+++ b/sys/arch/armv7/imx/imxenet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxenet.c,v 1.17 2015/10/27 15:07:56 mpi Exp $ */
+/* $OpenBSD: imxenet.c,v 1.18 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -816,16 +816,17 @@ imxenet_start(struct ifnet *ifp)
return;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (imxenet_encap(sc, m_head)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
ifp->if_opackets++;
diff --git a/sys/arch/armv7/sunxi/sxie.c b/sys/arch/armv7/sunxi/sxie.c
index 3a7f2fb8031..15c2eaa8548 100644
--- a/sys/arch/armv7/sunxi/sxie.c
+++ b/sys/arch/armv7/sunxi/sxie.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxie.c,v 1.10 2015/10/27 15:07:56 mpi Exp $ */
+/* $OpenBSD: sxie.c,v 1.11 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2013 Artturi Alm
@@ -471,17 +471,19 @@ sxie_start(struct ifnet *ifp)
m = NULL;
head = NULL;
trynext:
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
return;
if (m->m_pkthdr.len > SXIE_MAX_PKT_SIZE) {
+ ifq_deq_commit(&ifp->if_snd, m);
printf("sxie_start: packet too big\n");
m_freem(m);
return;
}
if (sc->txf_inuse > 1) {
+ ifq_deq_rollback(&ifp->if_snd, m);
printf("sxie_start: tx fifos in use.\n");
ifp->if_flags |= IFF_OACTIVE;
return;
@@ -505,7 +507,7 @@ trynext:
/* transmit to PHY from fifo */
SXISET4(sc, SXIE_TXCR0 + (fifo * 4), 1);
ifp->if_timer = 5;
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/arch/sgi/dev/if_iec.c b/sys/arch/sgi/dev/if_iec.c
index 90629b2400b..39d5a61a4d2 100644
--- a/sys/arch/sgi/dev/if_iec.c
+++ b/sys/arch/sgi/dev/if_iec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iec.c,v 1.16 2015/10/25 13:22:09 mpi Exp $ */
+/* $OpenBSD: if_iec.c,v 1.17 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -760,12 +760,14 @@ iec_start(struct ifnet *ifp)
for (;;) {
/* Grab a packet off the queue. */
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
- if (sc->sc_txpending == IEC_NTXDESC)
+ if (sc->sc_txpending == IEC_NTXDESC) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
/*
* Get the next available transmit descriptor.
@@ -779,7 +781,7 @@ iec_start(struct ifnet *ifp)
DPRINTF(IEC_DEBUG_START,
("iec_start: len = %d, nexttx = %d\n", len, nexttx));
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (len <= IEC_TXD_BUFSIZE) {
/*
* If the packet is small enough,
diff --git a/sys/arch/sgi/dev/if_mec.c b/sys/arch/sgi/dev/if_mec.c
index 97e64c1afa0..25d83dd797a 100644
--- a/sys/arch/sgi/dev/if_mec.c
+++ b/sys/arch/sgi/dev/if_mec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mec.c,v 1.31 2015/10/25 13:22:09 mpi Exp $ */
+/* $OpenBSD: if_mec.c,v 1.32 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: if_mec_mace.c,v 1.5 2004/08/01 06:36:36 tsutsui Exp $ */
/*
@@ -738,11 +738,12 @@ mec_start(struct ifnet *ifp)
for (;;) {
/* Grab a packet off the queue. */
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (sc->sc_txpending == MEC_NTXDESC) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
@@ -763,7 +764,7 @@ mec_start(struct ifnet *ifp)
DPRINTF(MEC_DEBUG_START,
("mec_start: len = %d, nexttx = %d\n", len, nexttx));
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (len < ETHER_PAD_LEN) {
/*
* I don't know if MEC chip does auto padding,
diff --git a/sys/arch/sgi/hpc/if_sq.c b/sys/arch/sgi/hpc/if_sq.c
index 620f52af5b3..c79b06b2871 100644
--- a/sys/arch/sgi/hpc/if_sq.c
+++ b/sys/arch/sgi/hpc/if_sq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sq.c,v 1.18 2015/10/25 13:22:09 mpi Exp $ */
+/* $OpenBSD: if_sq.c,v 1.19 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: if_sq.c,v 1.42 2011/07/01 18:53:47 dyoung Exp $ */
/*
@@ -671,7 +671,7 @@ sq_start(struct ifnet *ifp)
/*
* Grab a packet off the queue.
*/
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd, m0);
if (m0 == NULL)
break;
m = NULL;
@@ -696,6 +696,7 @@ sq_start(struct ifnet *ifp)
BUS_DMA_NOWAIT) != 0) {
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to allocate Tx mbuf\n",
sc->sc_dev.dv_xname);
break;
@@ -703,6 +704,7 @@ sq_start(struct ifnet *ifp)
if (len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to allocate Tx "
"cluster\n",
sc->sc_dev.dv_xname);
@@ -722,6 +724,7 @@ sq_start(struct ifnet *ifp)
if ((err = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
m, BUS_DMA_NOWAIT)) != 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to load Tx buffer, "
"error = %d\n",
sc->sc_dev.dv_xname, err);
@@ -734,6 +737,7 @@ sq_start(struct ifnet *ifp)
* the packet.
*/
if (dmamap->dm_nsegs > sc->sc_nfreetx) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
/*
* Not enough free descriptors to transmit this
* packet. We haven't committed to anything yet,
@@ -751,7 +755,7 @@ sq_start(struct ifnet *ifp)
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
/*
* Pass the packet to any BPF listeners.
diff --git a/sys/arch/socppc/dev/if_tsec.c b/sys/arch/socppc/dev/if_tsec.c
index 667ce15da69..2fb835c3cb7 100644
--- a/sys/arch/socppc/dev/if_tsec.c
+++ b/sys/arch/socppc/dev/if_tsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tsec.c,v 1.39 2015/11/06 11:35:48 mpi Exp $ */
+/* $OpenBSD: if_tsec.c,v 1.40 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
@@ -527,24 +527,25 @@ tsec_start(struct ifnet *ifp)
idx = sc->sc_tx_prod;
while ((sc->sc_txdesc[idx].td_status & TSEC_TX_TO1) == 0) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
error = tsec_encap(sc, m, &idx);
if (error == ENOBUFS) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
if (error == EFBIG) {
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m); /* give up: drop it */
ifp->if_oerrors++;
continue;
}
/* Now we are committed to transmit the packet. */
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c
index ec19e013526..21943833f67 100644
--- a/sys/arch/sparc64/dev/vnet.c
+++ b/sys/arch/sparc64/dev/vnet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnet.c,v 1.47 2015/10/25 13:22:09 mpi Exp $ */
+/* $OpenBSD: vnet.c,v 1.48 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2009, 2015 Mark Kettenis
*
@@ -1101,24 +1101,26 @@ vnet_start(struct ifnet *ifp)
start = prod = sc->sc_tx_prod & (sc->sc_vd->vd_nentries - 1);
while (sc->sc_vd->vd_desc[prod].hdr.dstate == VIO_DESC_FREE) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
count = sc->sc_tx_prod - sc->sc_tx_cons;
if (count >= (sc->sc_vd->vd_nentries - 1) ||
map->lm_count >= map->lm_nentries) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
buf = pool_get(&sc->sc_pool, PR_NOWAIT|PR_ZERO);
if (buf == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
m_copydata(m, 0, m->m_pkthdr.len, buf + VNET_ETHER_ALIGN);
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
/*
@@ -1176,24 +1178,26 @@ vnet_start_desc(struct ifnet *ifp)
u_int prod, count;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
count = sc->sc_tx_prod - sc->sc_tx_cons;
if (count >= (sc->sc_vd->vd_nentries - 1) ||
map->lm_count >= map->lm_nentries) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
return;
}
buf = pool_get(&sc->sc_pool, PR_NOWAIT|PR_ZERO);
if (buf == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
return;
}
m_copydata(m, 0, m->m_pkthdr.len, buf);
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
/*
diff --git a/sys/arch/vax/if/if_qe.c b/sys/arch/vax/if/if_qe.c
index 137fd914a4c..065dfae355a 100644
--- a/sys/arch/vax/if/if_qe.c
+++ b/sys/arch/vax/if/if_qe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_qe.c,v 1.37 2015/11/14 17:26:40 mpi Exp $ */
+/* $OpenBSD: if_qe.c,v 1.38 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: if_qe.c,v 1.51 2002/06/08 12:28:37 ragge Exp $ */
/*
* Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
@@ -442,7 +442,7 @@ qestart(struct ifnet *ifp)
continue;
}
idx = sc->sc_nexttx;
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd, m);
if (m == NULL)
goto out;
/*
@@ -457,11 +457,12 @@ qestart(struct ifnet *ifp)
panic("qestart");
if ((i + sc->sc_inq) >= (TXDESCS - 1)) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
goto out;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/ic/aic6915.c b/sys/dev/ic/aic6915.c
index fd90f712c38..13150cb0e93 100644
--- a/sys/dev/ic/aic6915.c
+++ b/sys/dev/ic/aic6915.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aic6915.c,v 1.18 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: aic6915.c,v 1.19 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: aic6915.c,v 1.15 2005/12/24 20:27:29 perry Exp $ */
/*-
@@ -363,7 +363,7 @@ sf_start(struct ifnet *ifp)
/*
* Grab a packet off the queue.
*/
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
m = NULL;
@@ -385,6 +385,7 @@ sf_start(struct ifnet *ifp)
BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) {
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to allocate Tx mbuf\n",
sc->sc_dev.dv_xname);
break;
@@ -392,6 +393,7 @@ sf_start(struct ifnet *ifp)
if (m0->m_pkthdr.len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to allocate Tx "
"cluster\n", sc->sc_dev.dv_xname);
m_freem(m);
@@ -403,6 +405,7 @@ sf_start(struct ifnet *ifp)
error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
printf("%s: unable to load Tx buffer, "
"error = %d\n", sc->sc_dev.dv_xname, error);
m_freem(m);
@@ -413,7 +416,7 @@ sf_start(struct ifnet *ifp)
/*
* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
*/
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m != NULL) {
m_freem(m0);
m0 = m;
diff --git a/sys/dev/ic/an.c b/sys/dev/ic/an.c
index 1d29bfed8db..abb6bac0ac2 100644
--- a/sys/dev/ic/an.c
+++ b/sys/dev/ic/an.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: an.c,v 1.66 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: an.c,v 1.67 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: an.c,v 1.34 2005/06/20 02:49:18 atatat Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -1097,18 +1097,19 @@ an_start(struct ifnet *ifp)
DPRINTF(("an_start: not running %d\n", ic->ic_state));
break;
}
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL) {
DPRINTF2(("an_start: no pending mbuf\n"));
break;
}
if (sc->sc_txd[cur].d_inuse) {
+ ifq_deq_rollback(&ifp->if_snd, m);
DPRINTF2(("an_start: %x/%d busy\n",
sc->sc_txd[cur].d_fid, cur));
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
ifp->if_opackets++;
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/ic/dc.c b/sys/dev/ic/dc.c
index 6a4a903cfe5..e45edf8f7d9 100644
--- a/sys/dev/ic/dc.c
+++ b/sys/dev/ic/dc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dc.c,v 1.145 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: dc.c,v 1.146 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -2618,7 +2618,7 @@ dc_start(struct ifnet *ifp)
idx = sc->dc_cdata.dc_tx_prod;
while(sc->dc_cdata.dc_tx_chain[idx].sd_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
@@ -2628,7 +2628,7 @@ dc_start(struct ifnet *ifp)
/* note: dc_coal breaks the poll-and-dequeue rule.
* if dc_coal fails, we lose the packet.
*/
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
if (dc_coal(sc, &m_head)) {
ifp->if_flags |= IFF_OACTIVE;
break;
@@ -2636,6 +2636,9 @@ dc_start(struct ifnet *ifp)
}
if (dc_encap(sc, m_head, &idx)) {
+ if ((sc->dc_flags & DC_TX_COALESCE) == 0)
+ ifq_deq_rollback(&ifp->if_snd, m_head);
+
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -2644,7 +2647,7 @@ dc_start(struct ifnet *ifp)
if (sc->dc_flags & DC_TX_COALESCE) {
/* if mbuf is coalesced, it is already dequeued */
} else
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
/*
* If there's a BPF listener, bounce a copy of this frame
diff --git a/sys/dev/ic/elink3.c b/sys/dev/ic/elink3.c
index 328a60e8495..726adc476bd 100644
--- a/sys/dev/ic/elink3.c
+++ b/sys/dev/ic/elink3.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: elink3.c,v 1.88 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: elink3.c,v 1.89 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: elink3.c,v 1.32 1997/05/14 00:22:00 thorpej Exp $ */
/*
@@ -954,7 +954,7 @@ epstart(struct ifnet *ifp)
startagain:
/* Sneak a peek at the next packet */
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
return;
@@ -973,7 +973,7 @@ startagain:
if (len + pad > ETHER_MAX_LEN) {
/* packet is obviously too large: toss it */
++ifp->if_oerrors;
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
m_freem(m0);
goto readcheck;
}
@@ -983,6 +983,7 @@ startagain:
bus_space_write_2(iot, ioh, EP_COMMAND,
SET_TX_AVAIL_THRESH | ((len + pad + 4) >> sc->txashift));
/* not enough room in FIFO */
+ ifq_deq_rollback(&ifp->if_snd, m0);
ifp->if_flags |= IFF_OACTIVE;
return;
} else {
@@ -990,7 +991,7 @@ startagain:
SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m0 == NULL)
return;
diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c
index 78388fc26d7..e31e1863368 100644
--- a/sys/dev/ic/fxp.c
+++ b/sys/dev/ic/fxp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fxp.c,v 1.123 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: fxp.c,v 1.124 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */
/*
@@ -689,19 +689,22 @@ fxp_start(struct ifnet *ifp)
txs = txs->tx_next;
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
m0, BUS_DMA_NOWAIT) != 0) {
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ if (m == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
if (m0->m_pkthdr.len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
m_freem(m);
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
}
@@ -710,11 +713,12 @@ fxp_start(struct ifnet *ifp)
if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
m, BUS_DMA_NOWAIT) != 0) {
m_freem(m);
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m != NULL) {
m_freem(m0);
m0 = m;
diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c
index 62cc2070bce..f00ada669fe 100644
--- a/sys/dev/ic/gem.c
+++ b/sys/dev/ic/gem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gem.c,v 1.114 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: gem.c,v 1.115 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: gem.c,v 1.1 2001/09/16 00:11:43 eeh Exp $ */
/*
@@ -1657,7 +1657,7 @@ gem_start(struct ifnet *ifp)
return;
while (sc->sc_txd[sc->sc_tx_prod].sd_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
@@ -1685,12 +1685,13 @@ gem_start(struct ifnet *ifp)
if ((sc->sc_tx_cnt + map->dm_nsegs) > (GEM_NTXDESC - 2)) {
bus_dmamap_unload(sc->sc_dmatag, map);
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* We are now committed to transmitting the packet. */
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
/*
@@ -1736,7 +1737,7 @@ gem_start(struct ifnet *ifp)
return;
drop:
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
ifp->if_oerrors++;
}
diff --git a/sys/dev/ic/hme.c b/sys/dev/ic/hme.c
index 41da924046a..b946c441dfb 100644
--- a/sys/dev/ic/hme.c
+++ b/sys/dev/ic/hme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hme.c,v 1.75 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: hme.c,v 1.76 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: hme.c,v 1.21 2001/07/07 15:59:37 thorpej Exp $ */
/*-
@@ -644,7 +644,7 @@ hme_start(struct ifnet *ifp)
return;
while (sc->sc_txd[sc->sc_tx_prod].sd_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
@@ -672,12 +672,13 @@ hme_start(struct ifnet *ifp)
if ((HME_TX_RING_SIZE - (sc->sc_tx_cnt + map->dm_nsegs)) < 5) {
bus_dmamap_unload(sc->sc_dmatag, map);
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* We are now committed to transmitting the packet. */
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
#if NBPFILTER > 0
/*
@@ -732,7 +733,7 @@ hme_start(struct ifnet *ifp)
return;
drop:
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
ifp->if_oerrors++;
}
diff --git a/sys/dev/ic/lemac.c b/sys/dev/ic/lemac.c
index 9b9a8bdcd18..c9c1078f1ed 100644
--- a/sys/dev/ic/lemac.c
+++ b/sys/dev/ic/lemac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lemac.c,v 1.22 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: lemac.c,v 1.23 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: lemac.c,v 1.20 2001/06/13 10:46:02 wiz Exp $ */
/*-
@@ -641,13 +641,14 @@ lemac_ifstart(struct ifnet *ifp)
struct mbuf *m0;
int tx_pg;
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
if ((sc->sc_csr.csr_tqc = LEMAC_INB(sc, LEMAC_REG_TQC)) >=
lemac_txmax) {
sc->sc_cntrs.cntr_txfull++;
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -662,11 +663,12 @@ lemac_ifstart(struct ifnet *ifp)
*/
if (tx_pg == 0 || tx_pg > sc->sc_lastpage) {
sc->sc_cntrs.cntr_txnospc++;
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
/*
* The first four bytes of each transmit buffer are for
diff --git a/sys/dev/ic/pgt.c b/sys/dev/ic/pgt.c
index ef6c8174a31..aa35c109a6b 100644
--- a/sys/dev/ic/pgt.c
+++ b/sys/dev/ic/pgt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pgt.c,v 1.79 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: pgt.c,v 1.80 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -2120,15 +2120,17 @@ pgt_start(struct ifnet *ifp)
for (; sc->sc_dirtyq_count[PGT_QUEUE_DATA_LOW_TX] <
PGT_QUEUE_FULL_THRESHOLD && !IFQ_IS_EMPTY(&ifp->if_snd);) {
pd = TAILQ_FIRST(&sc->sc_freeq[PGT_QUEUE_DATA_LOW_TX]);
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
if (m->m_pkthdr.len <= PGT_FRAG_SIZE) {
error = pgt_load_tx_desc_frag(sc,
PGT_QUEUE_DATA_LOW_TX, pd);
- if (error)
+ if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m);
break;
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ }
+ ifq_deq_commit(&ifp->if_snd, m);
m_copydata(m, 0, m->m_pkthdr.len, pd->pd_mem);
pgt_desc_transmit(sc, PGT_QUEUE_DATA_LOW_TX,
pd, m->m_pkthdr.len, 0);
@@ -2142,8 +2144,10 @@ pgt_start(struct ifnet *ifp)
* even support a full two.)
*/
if (sc->sc_dirtyq_count[PGT_QUEUE_DATA_LOW_TX] + 2 >
- PGT_QUEUE_FULL_THRESHOLD)
+ PGT_QUEUE_FULL_THRESHOLD) {
+ ifq_deq_rollback(&ifp->if_snd, m);
break;
+ }
pd2 = TAILQ_NEXT(pd, pd_link);
error = pgt_load_tx_desc_frag(sc,
PGT_QUEUE_DATA_LOW_TX, pd);
@@ -2157,9 +2161,11 @@ pgt_start(struct ifnet *ifp)
pd_link);
}
}
- if (error)
+ if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m);
break;
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ }
+ ifq_deq_commit(&ifp->if_snd, m);
m_copydata(m, 0, PGT_FRAG_SIZE, pd->pd_mem);
pgt_desc_transmit(sc, PGT_QUEUE_DATA_LOW_TX,
pd, PGT_FRAG_SIZE, 1);
@@ -2168,7 +2174,7 @@ pgt_start(struct ifnet *ifp)
pgt_desc_transmit(sc, PGT_QUEUE_DATA_LOW_TX,
pd2, m->m_pkthdr.len - PGT_FRAG_SIZE, 0);
} else {
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
ifp->if_oerrors++;
m_freem(m);
m = NULL;
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index 7161304df00..2f0c2ca5c98 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.183 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: re.c,v 1.184 2015/11/20 03:35:22 dlg Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -1848,29 +1848,31 @@ re_start(struct ifnet *ifp)
idx = sc->rl_ldata.rl_txq_prodidx;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
if (sc->rl_ldata.rl_txq[idx].txq_mbuf != NULL) {
KASSERT(idx == sc->rl_ldata.rl_txq_considx);
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
error = re_encap(sc, m, &idx);
if (error != 0 && error != ENOBUFS) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
} else if (error != 0) {
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
ifp->if_oerrors++;
continue;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
queued++;
#if NBPFILTER > 0
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c
index e766fe3cb0a..75b69c79cb2 100644
--- a/sys/dev/ic/rt2560.c
+++ b/sys/dev/ic/rt2560.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2560.c,v 1.74 2015/11/04 12:11:59 dlg Exp $ */
+/* $OpenBSD: rt2560.c,v 1.75 2015/11/20 03:35:22 dlg Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -1948,15 +1948,16 @@ rt2560_start(struct ifnet *ifp)
} else {
if (ic->ic_state != IEEE80211_S_RUN)
break;
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
ifp->if_flags |= IFF_OACTIVE;
sc->sc_flags |= RT2560_DATA_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c
index 55fed910a64..1fefe88c366 100644
--- a/sys/dev/ic/rt2661.c
+++ b/sys/dev/ic/rt2661.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2661.c,v 1.84 2015/11/04 12:11:59 dlg Exp $ */
+/* $OpenBSD: rt2661.c,v 1.85 2015/11/20 03:35:22 dlg Exp $ */
/*-
* Copyright (c) 2006
@@ -1952,15 +1952,16 @@ rt2661_start(struct ifnet *ifp)
} else {
if (ic->ic_state != IEEE80211_S_RUN)
break;
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (sc->txq[0].queued >= RT2661_TX_RING_COUNT - 1) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
/* there is no place left in this ring */
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
diff --git a/sys/dev/ic/rtw.c b/sys/dev/ic/rtw.c
index 07c66cb5dfb..ebf94678520 100644
--- a/sys/dev/ic/rtw.c
+++ b/sys/dev/ic/rtw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtw.c,v 1.92 2015/11/04 12:11:59 dlg Exp $ */
+/* $OpenBSD: rtw.c,v 1.93 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */
/*-
@@ -2755,7 +2755,7 @@ rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
*mp = NULL;
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL) {
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
__func__));
@@ -2764,12 +2764,13 @@ rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) {
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__));
+ ifq_deq_rollback(&ifp->if_snd, m0);
*if_flagsp |= IFF_OACTIVE;
sc->sc_if.if_timer = 1;
return 0;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m0 == NULL) {
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n",
__func__));
diff --git a/sys/dev/ic/smc83c170.c b/sys/dev/ic/smc83c170.c
index c5cf4458a3d..8940373ec28 100644
--- a/sys/dev/ic/smc83c170.c
+++ b/sys/dev/ic/smc83c170.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smc83c170.c,v 1.23 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: smc83c170.c,v 1.24 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: smc83c170.c,v 1.59 2005/02/27 00:27:02 perry Exp $ */
/*-
@@ -352,7 +352,7 @@ epic_start(struct ifnet *ifp)
/*
* Grab a packet off the queue.
*/
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
m = NULL;
@@ -380,12 +380,15 @@ epic_start(struct ifnet *ifp)
bus_dmamap_unload(sc->sc_dmat, dmamap);
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ if (m == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
if (m0->m_pkthdr.len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
}
@@ -393,10 +396,12 @@ epic_start(struct ifnet *ifp)
m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
- if (error)
+ if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m != NULL) {
m_freem(m0);
m0 = m;
diff --git a/sys/dev/ic/smc91cxx.c b/sys/dev/ic/smc91cxx.c
index 22f13c0b086..6d36e9a75f0 100644
--- a/sys/dev/ic/smc91cxx.c
+++ b/sys/dev/ic/smc91cxx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smc91cxx.c,v 1.42 2015/10/25 12:48:46 mpi Exp $ */
+/* $OpenBSD: smc91cxx.c,v 1.43 2015/11/20 03:35:22 dlg Exp $ */
/* $NetBSD: smc91cxx.c,v 1.11 1998/08/08 23:51:41 mycroft Exp $ */
/*-
@@ -548,7 +548,7 @@ smc91cxx_start(ifp)
/*
* Peek at the next packet.
*/
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
return;
@@ -568,7 +568,7 @@ smc91cxx_start(ifp)
if ((len + pad) > (ETHER_MAX_LEN - ETHER_CRC_LEN)) {
printf("%s: large packet discarded\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
goto readcheck;
}
@@ -620,6 +620,7 @@ smc91cxx_start(ifp)
ifp->if_timer = 5;
ifp->if_flags |= IFF_OACTIVE;
+ ifq_deq_rollback(&ifp->if_snd, m);
return;
}
@@ -645,7 +646,7 @@ smc91cxx_start(ifp)
* Get the packet from the kernel. This will include the Ethernet
* frame header, MAC address, etc.
*/
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
/*
* Push the packet out to the card.
diff --git a/sys/dev/ic/ti.c b/sys/dev/ic/ti.c
index e40dd748c25..fb49a965d6c 100644
--- a/sys/dev/ic/ti.c
+++ b/sys/dev/ic/ti.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ti.c,v 1.19 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: ti.c,v 1.20 2015/11/20 03:35:22 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -1961,7 +1961,7 @@ ti_start(struct ifnet *ifp)
prodidx = sc->ti_tx_saved_prodidx;
while(sc->ti_cdata.ti_tx_chain[prodidx] == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
@@ -1976,12 +1976,13 @@ ti_start(struct ifnet *ifp)
error = ti_encap_tigon2(sc, m_head, &prodidx);
if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
pkts++;
/*
diff --git a/sys/dev/isa/if_ef_isapnp.c b/sys/dev/isa/if_ef_isapnp.c
index 62caa7f6d3d..cb004cea46e 100644
--- a/sys/dev/isa/if_ef_isapnp.c
+++ b/sys/dev/isa/if_ef_isapnp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ef_isapnp.c,v 1.31 2015/10/25 13:13:06 mpi Exp $ */
+/* $OpenBSD: if_ef_isapnp.c,v 1.32 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -243,7 +243,7 @@ efstart(ifp)
return;
startagain:
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
return;
@@ -254,7 +254,7 @@ startagain:
if (len + pad > ETHER_MAX_LEN) {
ifp->if_oerrors++;
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
m_freem(m0);
goto startagain;
}
@@ -262,6 +262,7 @@ startagain:
if (bus_space_read_2(iot, ioh, EF_W1_FREE_TX) < len + pad + 4) {
bus_space_write_2(iot, ioh, EP_COMMAND,
SET_TX_AVAIL_THRESH | ((len + pad) >> 2));
+ ifq_deq_rollback(&ifp->if_snd, m0);
ifp->if_flags |= IFF_OACTIVE;
return;
} else {
@@ -277,7 +278,7 @@ startagain:
bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
#endif
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m0 == NULL) /* XXX not needed */
return;
diff --git a/sys/dev/isa/if_ex.c b/sys/dev/isa/if_ex.c
index 7c2d29a43f2..147dbcf27a8 100644
--- a/sys/dev/isa/if_ex.c
+++ b/sys/dev/isa/if_ex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ex.c,v 1.41 2015/10/25 13:13:06 mpi Exp $ */
+/* $OpenBSD: if_ex.c,v 1.42 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1997, Donald A. Schmidt
* Copyright (c) 1996, Javier Martín Rueda (jmrueda@diatel.upm.es)
@@ -389,7 +389,7 @@ ex_start(struct ifnet *ifp)
* more packets left, or the card cannot accept any more yet.
*/
while (!(ifp->if_flags & IFF_OACTIVE)) {
- IFQ_POLL(&ifp->if_snd, opkt);
+ opkt = ifq_deq_begin(&ifp->if_snd);
if (opkt == NULL)
break;
@@ -414,7 +414,7 @@ ex_start(struct ifnet *ifp)
avail = -i;
DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail););
if (avail >= len + XMT_HEADER_LEN) {
- IFQ_DEQUEUE(&ifp->if_snd, opkt);
+ ifq_deq_commit(&ifp->if_snd, opkt);
#ifdef EX_PSA_INTR
/*
@@ -519,6 +519,7 @@ ex_start(struct ifnet *ifp)
ifp->if_opackets++;
m_freem(opkt);
} else {
+ ifq_deq_rollback(&ifp->if_snd, opkt);
ifp->if_flags |= IFF_OACTIVE;
DODEBUG(Status, printf("OACTIVE start\n"););
}
diff --git a/sys/dev/pci/if_bce.c b/sys/dev/pci/if_bce.c
index 7c51e70c10e..1c5a5208753 100644
--- a/sys/dev/pci/if_bce.c
+++ b/sys/dev/pci/if_bce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bce.c,v 1.47 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_bce.c,v 1.48 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_bce.c,v 1.3 2003/09/29 01:53:02 mrg Exp $ */
/*
@@ -535,7 +535,7 @@ bce_start(struct ifnet *ifp)
while (txsfree > 0) {
/* Grab a packet off the queue. */
- IFQ_POLL(&ifp->if_snd, m0);
+ IFQ_DEQUEUE(&ifp->if_snd, m0);
if (m0 == NULL)
break;
@@ -547,9 +547,6 @@ bce_start(struct ifnet *ifp)
ctrl = m0->m_pkthdr.len & CTRL_BC_MASK;
ctrl |= CTRL_SOF | CTRL_EOF | CTRL_IOC;
- /* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. */
- IFQ_DEQUEUE(&ifp->if_snd, m0);
-
#if NBPFILTER > 0
/* Pass the packet to any BPF listeners. */
if (ifp->if_bpf)
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index 051a3c592ae..e839c226a8b 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnx.c,v 1.115 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.116 2015/11/20 03:35:23 dlg Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -5006,7 +5006,7 @@ bnx_start(struct ifnet *ifp)
*/
while (sc->used_tx_bd < sc->max_tx_bd) {
/* Check for any frames to send. */
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
@@ -5016,6 +5016,7 @@ bnx_start(struct ifnet *ifp)
* for the NIC to drain the chain.
*/
if (bnx_tx_encap(sc, m_head)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
DBPRINT(sc, BNX_INFO_SEND, "TX chain is closed for "
"business! Total tx_bd used = %d\n",
@@ -5023,7 +5024,7 @@ bnx_start(struct ifnet *ifp)
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
count++;
#if NBPFILTER > 0
diff --git a/sys/dev/pci/if_cas.c b/sys/dev/pci/if_cas.c
index 7334b390c3e..7035cae3964 100644
--- a/sys/dev/pci/if_cas.c
+++ b/sys/dev/pci/if_cas.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cas.c,v 1.43 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_cas.c,v 1.44 2015/11/20 03:35:23 dlg Exp $ */
/*
*
@@ -1863,7 +1863,7 @@ cas_start(struct ifnet *ifp)
bix = sc->sc_tx_prod;
while (sc->sc_txd[bix].sd_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
@@ -1881,11 +1881,12 @@ cas_start(struct ifnet *ifp)
* or fail...
*/
if (cas_encap(sc, m, &bix)) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
ifp->if_timer = 5;
}
diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c
index 7c5c31299de..16cef9fb3b1 100644
--- a/sys/dev/pci/if_de.c
+++ b/sys/dev/pci/if_de.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_de.c,v 1.126 2015/11/04 00:10:50 dlg Exp $ */
+/* $OpenBSD: if_de.c,v 1.127 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_de.c,v 1.58 1998/01/12 09:39:58 thorpej Exp $ */
/*-
@@ -3800,12 +3800,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue)
int segcnt, freedescs;
u_int32_t d_status;
bus_dmamap_t map;
- int error;
struct ifnet *ifp = &sc->tulip_if;
-#ifdef DIAGNOSTIC
- struct mbuf *ombuf = m;
-#endif
- int compressed = 0;
#if defined(TULIP_DEBUG)
if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
@@ -3858,47 +3853,24 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue)
#endif
goto finish;
}
- error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT);
- if (error != 0) {
- if (error == EFBIG) {
- /*
- * The packet exceeds the number of transmit buffer
- * entries that we can use for one packet, so we have
- * to recopy it into one mbuf and then try again.
- */
- struct mbuf *tmp;
- if (!notonqueue) {
-#ifdef DIAGNOSTIC
- if (IFQ_IS_EMPTY(&ifp->if_snd))
- panic("%s: if_snd queue empty", ifp->if_xname);
-#endif
- IFQ_DEQUEUE(&ifp->if_snd, tmp);
-#ifdef DIAGNOSTIC
- if (tmp != ombuf)
- panic("tulip_txput: different mbuf dequeued!");
-#endif
- }
- compressed = 1;
- m = tulip_mbuf_compress(m);
- if (m == NULL) {
-#if defined(TULIP_DEBUG)
- sc->tulip_dbg.dbg_txput_finishes[2]++;
-#endif
- tulip_free_txmap(sc, map);
- goto finish;
- }
- error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT);
- }
- if (error != 0) {
- printf(TULIP_PRINTF_FMT ": unable to load tx map, "
- "error = %d\n", TULIP_PRINTF_ARGS, error);
-#if defined(TULIP_DEBUG)
- sc->tulip_dbg.dbg_txput_finishes[3]++;
-#endif
- tulip_free_txmap(sc, map);
- goto finish;
- }
+ switch (bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT)) {
+ case 0:
+ break;
+ case EFBIG:
+ /*
+ * The packet exceeds the number of transmit buffer
+ * entries that we can use for one packet, so we have
+ * to recopy it into one mbuf and then try again.
+ */
+ if (m_defrag(m, M_DONTWAIT) == 0 &&
+ bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT) == 0)
+ break;
+ /* FALLTHROUGH */
+ default:
+ tulip_free_txmap(sc, map);
+ goto finish;
}
+
if ((freedescs -= (map->dm_nsegs + 1) / 2) <= 0
/*
* See if there's any unclaimed space in the transmit ring.
@@ -3949,19 +3921,8 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m, int notonqueue)
* The descriptors have been filled in. Now get ready
* to transmit.
*/
- if (!compressed && !notonqueue) {
- /* remove the mbuf from the queue */
- struct mbuf *tmp;
-#ifdef DIAGNOSTIC
- if (IFQ_IS_EMPTY(&ifp->if_snd))
- panic("%s: if_snd queue empty", ifp->if_xname);
-#endif
- IFQ_DEQUEUE(&ifp->if_snd, tmp);
-#ifdef DIAGNOSTIC
- if (tmp != ombuf)
- panic("tulip_txput: different mbuf dequeued!");
-#endif
- }
+ if (!notonqueue)
+ ifq_deq_commit(&ifp->if_snd, m);
ml_enqueue(&sc->tulip_txq, m);
m = NULL;
@@ -4198,21 +4159,21 @@ tulip_ifstart(struct ifnet * const ifp)
{
TULIP_PERFSTART(ifstart)
tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
+ struct mbuf *m, *m0;
if (sc->tulip_if.if_flags & IFF_RUNNING) {
if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
tulip_txput_setup(sc);
- while (!IFQ_IS_EMPTY(&sc->tulip_if.if_snd)) {
- struct mbuf *m, *m0;
- IFQ_POLL(&sc->tulip_if.if_snd, m);
+ for (;;) {
+ m = ifq_deq_begin(&sc->tulip_if.if_snd);
if (m == NULL)
break;
- if ((m0 = tulip_txput(sc, m, 0)) != NULL) {
- if (m0 != m)
- /* should not happen */
- printf("tulip_if_start: txput failed!\n");
+ m0 = tulip_txput(sc, m, 0);
+ if (m0 != NULL) {
+ KASSERT(m == m0);
+ ifq_deq_rollback(&sc->tulip_if.if_snd, m);
break;
}
}
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index f8d4b7d064e..31d7d2336d4 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.310 2015/10/29 03:19:42 jsg Exp $ */
+/* $OpenBSD: if_em.c,v 1.311 2015/11/20 03:35:23 dlg Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -605,16 +605,17 @@ em_start(struct ifnet *ifp)
}
for (;;) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (em_encap(sc, m_head)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/* Send a copy of the frame to the BPF listener */
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index 4c8a496c8b9..05480c89b76 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ipw.c,v 1.110 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_ipw.c,v 1.111 2015/11/20 03:35:23 dlg Exp $ */
/*-
* Copyright (c) 2004-2008
@@ -1299,19 +1299,20 @@ ipw_start(struct ifnet *ifp)
return;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m);
- if (m == NULL)
- break;
-
if (sc->txfree < 1 + IPW_MAX_NSEG) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
+
IFQ_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
+
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
#endif
+
m = ieee80211_encap(ifp, m, &ni);
if (m == NULL)
continue;
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index 3d93c2bca65..e24246400f0 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwi.c,v 1.127 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_iwi.c,v 1.128 2015/11/20 03:35:23 dlg Exp $ */
/*-
* Copyright (c) 2004-2008
@@ -1389,15 +1389,15 @@ iwi_start(struct ifnet *ifp)
return;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m0);
- if (m0 == NULL)
- break;
-
- if (sc->txq[0].queued >= IWI_TX_RING_COUNT - 8) {
+ if (sc->txq[0].queued + IWI_MAX_NSEG + 2 >= IWI_TX_RING_COUNT) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
+
IFQ_DEQUEUE(&ifp->if_snd, m0);
+ if (m0 == NULL)
+ break;
+
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c
index 6d1c0fe1062..8f12f70bcf1 100644
--- a/sys/dev/pci/if_ix.c
+++ b/sys/dev/pci/if_ix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.c,v 1.127 2015/11/04 00:20:35 dlg Exp $ */
+/* $OpenBSD: if_ix.c,v 1.128 2015/11/20 03:35:23 dlg Exp $ */
/******************************************************************************
@@ -378,16 +378,17 @@ ixgbe_start(struct ifnet * ifp)
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
for (;;) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (ixgbe_encap(txr, m_head)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/pci/if_ixgb.c b/sys/dev/pci/if_ixgb.c
index c9c524a2850..1f5282ab273 100644
--- a/sys/dev/pci/if_ixgb.c
+++ b/sys/dev/pci/if_ixgb.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_ixgb.c,v 1.66 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_ixgb.c,v 1.67 2015/11/20 03:35:23 dlg Exp $ */
#include <dev/pci/if_ixgb.h>
@@ -283,16 +283,17 @@ ixgb_start(struct ifnet *ifp)
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
for (;;) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (ixgb_encap(sc, m_head)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/* Send a copy of the frame to the BPF listener */
diff --git a/sys/dev/pci/if_lge.c b/sys/dev/pci/if_lge.c
index 7e5a7138069..31fbe7b35c1 100644
--- a/sys/dev/pci/if_lge.c
+++ b/sys/dev/pci/if_lge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lge.c,v 1.68 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_lge.c,v 1.69 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2000, 2001
@@ -956,17 +956,18 @@ lge_start(struct ifnet *ifp)
if (CSR_READ_1(sc, LGE_TXCMDFREE_8BIT) == 0)
break;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (lge_encap(sc, m_head, &idx)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
pkts++;
#if NBPFILTER > 0
diff --git a/sys/dev/pci/if_lii.c b/sys/dev/pci/if_lii.c
index 159b11912e5..ab8f9b97317 100644
--- a/sys/dev/pci/if_lii.c
+++ b/sys/dev/pci/if_lii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_lii.c,v 1.38 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_lii.c,v 1.39 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2007 The NetBSD Foundation.
@@ -798,12 +798,13 @@ lii_start(struct ifnet *ifp)
return;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (!sc->sc_free_tx_slots ||
lii_free_tx_space(sc) < m0->m_pkthdr.len) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -819,7 +820,7 @@ lii_start(struct ifnet *ifp)
LII_WRITE_2(sc, LII_MB_TXD_WR_IDX, sc->sc_txd_cur/4);
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c
index 948c23ad786..d1d9339797b 100644
--- a/sys/dev/pci/if_msk.c
+++ b/sys/dev/pci/if_msk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_msk.c,v 1.118 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_msk.c,v 1.119 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -1544,7 +1544,7 @@ msk_start(struct ifnet *ifp)
DPRINTFN(2, ("msk_start\n"));
while (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
@@ -1554,12 +1554,13 @@ msk_start(struct ifnet *ifp)
* for the NIC to drain the ring.
*/
if (msk_encap(sc_if, m_head, &idx)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
pkts++;
/*
diff --git a/sys/dev/pci/if_nep.c b/sys/dev/pci/if_nep.c
index 84de99ea56b..0af16e780bf 100644
--- a/sys/dev/pci/if_nep.c
+++ b/sys/dev/pci/if_nep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nep.c,v 1.20 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_nep.c,v 1.21 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2014, 2015 Mark Kettenis
*
@@ -1877,17 +1877,18 @@ nep_start(struct ifnet *ifp)
idx = sc->sc_tx_prod;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
if (sc->sc_tx_cnt >= (NEP_NTXDESC - NEP_NTXSEGS)) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* Now we are committed to transmit the packet. */
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
if (nep_encap(sc, &m, &idx))
break;
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c
index b33bfc9a321..a59393dfc81 100644
--- a/sys/dev/pci/if_nfe.c
+++ b/sys/dev/pci/if_nfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nfe.c,v 1.113 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_nfe.c,v 1.114 2015/11/20 03:35:23 dlg Exp $ */
/*-
* Copyright (c) 2006, 2007 Damien Bergamini <damien.bergamini@free.fr>
@@ -974,17 +974,18 @@ nfe_start(struct ifnet *ifp)
return;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
if (nfe_encap(sc, m0) != 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* packet put in h/w queue, remove from s/w queue */
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
diff --git a/sys/dev/pci/if_nge.c b/sys/dev/pci/if_nge.c
index d573d5955df..f1c89ec918e 100644
--- a/sys/dev/pci/if_nge.c
+++ b/sys/dev/pci/if_nge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nge.c,v 1.87 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_nge.c,v 1.88 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2000, 2001
@@ -1408,17 +1408,18 @@ nge_start(struct ifnet *ifp)
return;
while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (nge_encap(sc, m_head, &idx)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
pkts++;
#if NBPFILTER > 0
diff --git a/sys/dev/pci/if_nxe.c b/sys/dev/pci/if_nxe.c
index ca16738ac2f..d75f414c01d 100644
--- a/sys/dev/pci/if_nxe.c
+++ b/sys/dev/pci/if_nxe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nxe.c,v 1.68 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_nxe.c,v 1.69 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -1322,17 +1322,18 @@ nxe_start(struct ifnet *ifp)
bzero(txd, sizeof(struct nxe_tx_desc));
do {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
pkt = nxe_pkt_get(sc->sc_tx_pkts);
if (pkt == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m);
SET(ifp->if_flags, IFF_OACTIVE);
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
dmap = pkt->pkt_dmap;
m = nxe_load_pkt(sc, dmap, m);
diff --git a/sys/dev/pci/if_pcn.c b/sys/dev/pci/if_pcn.c
index 9e8467253a2..2f970cce7eb 100644
--- a/sys/dev/pci/if_pcn.c
+++ b/sys/dev/pci/if_pcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pcn.c,v 1.38 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_pcn.c,v 1.39 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_pcn.c,v 1.26 2005/05/07 09:15:44 is Exp $ */
/*
@@ -833,14 +833,16 @@ pcn_start(struct ifnet *ifp)
*/
for (;;) {
/* Grab a packet off the queue. */
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
m = NULL;
/* Get a work queue entry. */
- if (sc->sc_txsfree == 0)
+ if (sc->sc_txsfree == 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
txs = &sc->sc_txsoft[sc->sc_txsnext];
dmamap = txs->txs_dmamap;
@@ -854,11 +856,14 @@ pcn_start(struct ifnet *ifp)
if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) {
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ if (m == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
if (m0->m_pkthdr.len > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
m_freem(m);
break;
}
@@ -867,8 +872,10 @@ pcn_start(struct ifnet *ifp)
m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
- if (error)
+ if (error) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
}
/*
@@ -892,10 +899,11 @@ pcn_start(struct ifnet *ifp)
bus_dmamap_unload(sc->sc_dmat, dmamap);
if (m != NULL)
m_freem(m);
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
if (m != NULL) {
m_freem(m0);
m0 = m;
diff --git a/sys/dev/pci/if_se.c b/sys/dev/pci/if_se.c
index f1ebdc9ed3e..645b642ba1b 100644
--- a/sys/dev/pci/if_se.c
+++ b/sys/dev/pci/if_se.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_se.c,v 1.14 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_se.c,v 1.15 2015/11/20 03:35:23 dlg Exp $ */
/*-
* Copyright (c) 2009, 2010 Christopher Zimmermann <madroach@zakweb.de>
@@ -1217,17 +1217,18 @@ se_start(struct ifnet *ifp)
i = cd->se_tx_prod;
while (cd->se_tx_mbuf[i] == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (se_encap(sc, m_head, &i) != 0) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
queued++;
/*
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c
index 0127affd8ce..2538701bf71 100644
--- a/sys/dev/pci/if_sis.c
+++ b/sys/dev/pci/if_sis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sis.c,v 1.128 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_sis.c,v 1.129 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -1677,17 +1677,18 @@ sis_start(struct ifnet *ifp)
return;
while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
if (sis_encap(sc, m_head, &idx)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
queued++;
diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c
index 1dba8e67a28..5abc88c1244 100644
--- a/sys/dev/pci/if_sk.c
+++ b/sys/dev/pci/if_sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sk.c,v 1.179 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_sk.c,v 1.180 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -1498,7 +1498,7 @@ sk_start(struct ifnet *ifp)
DPRINTFN(2, ("sk_start\n"));
while (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
break;
@@ -1508,12 +1508,13 @@ sk_start(struct ifnet *ifp)
* for the NIC to drain the ring.
*/
if (sk_encap(sc_if, m_head, &idx)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
}
/* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
pkts++;
/*
diff --git a/sys/dev/pci/if_stge.c b/sys/dev/pci/if_stge.c
index 5c6db61ba53..4deaa8598c6 100644
--- a/sys/dev/pci/if_stge.c
+++ b/sys/dev/pci/if_stge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_stge.c,v 1.63 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_stge.c,v 1.64 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_stge.c,v 1.27 2005/05/16 21:35:32 bouyer Exp $ */
/*-
@@ -482,7 +482,7 @@ stge_start(struct ifnet *ifp)
/*
* Grab a packet off the queue.
*/
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
break;
@@ -490,8 +490,10 @@ stge_start(struct ifnet *ifp)
* Leave one unused descriptor at the end of the
* list to prevent wrapping completely around.
*/
- if (sc->sc_txpending == (STGE_NTXDESC - 1))
+ if (sc->sc_txpending == (STGE_NTXDESC - 1)) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
+ }
/*
* Get the last and next available transmit descriptor.
@@ -517,17 +519,18 @@ stge_start(struct ifnet *ifp)
printf("%s: Tx packet consumes too many "
"DMA segments (%u), dropping...\n",
sc->sc_dev.dv_xname, dmamap->dm_nsegs);
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
m_freem(m0);
continue;
}
/*
* Short on resources, just stop for now.
*/
+ ifq_deq_rollback(&ifp->if_snd, m0);
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
/*
* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
diff --git a/sys/dev/pci/if_tht.c b/sys/dev/pci/if_tht.c
index 4b4bf59af4e..d53d367a94c 100644
--- a/sys/dev/pci/if_tht.c
+++ b/sys/dev/pci/if_tht.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tht.c,v 1.134 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_tht.c,v 1.135 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -1111,17 +1111,18 @@ tht_start(struct ifnet *ifp)
tht_fifo_pre(sc, &sc->sc_txt);
do {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
pkt = tht_pkt_get(&sc->sc_tx_list);
if (pkt == NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
if (tht_load_pkt(sc, pkt, m) != 0) {
m_freem(m);
tht_pkt_put(&sc->sc_tx_list, pkt);
diff --git a/sys/dev/pci/if_txp.c b/sys/dev/pci/if_txp.c
index 03724f54fe0..aeb5e940dd0 100644
--- a/sys/dev/pci/if_txp.c
+++ b/sys/dev/pci/if_txp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txp.c,v 1.118 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_txp.c,v 1.119 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2001
@@ -1282,7 +1282,7 @@ txp_start(struct ifnet *ifp)
cnt = r->r_cnt;
while (1) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
mnew = NULL;
@@ -1307,7 +1307,7 @@ txp_start(struct ifnet *ifp)
}
m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t));
mnew->m_pkthdr.len = mnew->m_len = m->m_pkthdr.len;
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
m = mnew;
if (bus_dmamap_load_mbuf(sc->sc_dmat, sd->sd_map, m,
@@ -1394,7 +1394,7 @@ txp_start(struct ifnet *ifp)
* the packet.
*/
if (mnew == NULL)
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
ifp->if_timer = 5;
@@ -1436,6 +1436,7 @@ txp_start(struct ifnet *ifp)
oactive:
bus_dmamap_unload(sc->sc_dmat, sd->sd_map);
oactive1:
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
r->r_prod = firstprod;
r->r_cnt = firstcnt;
diff --git a/sys/dev/pci/if_vic.c b/sys/dev/pci/if_vic.c
index 2a94fb30106..ad7bcefedbc 100644
--- a/sys/dev/pci/if_vic.c
+++ b/sys/dev/pci/if_vic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vic.c,v 1.92 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_vic.c,v 1.93 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2006 Reyk Floeter <reyk@openbsd.org>
@@ -1053,12 +1053,13 @@ vic_start(struct ifnet *ifp)
break;
}
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
idx = sc->sc_data->vd_tx_nextidx;
if (idx >= sc->sc_data->vd_tx_length) {
+ ifq_deq_rollback(&ifp->if_snd, m);
printf("%s: tx idx is corrupt\n", DEVNAME(sc));
ifp->if_oerrors++;
break;
@@ -1068,6 +1069,7 @@ vic_start(struct ifnet *ifp)
txb = &sc->sc_txbuf[idx];
if (txb->txb_m != NULL) {
+ ifq_deq_rollback(&ifp->if_snd, m);
printf("%s: tx ring is corrupt\n", DEVNAME(sc));
sc->sc_data->vd_tx_stopped = 1;
ifp->if_oerrors++;
@@ -1078,7 +1080,7 @@ vic_start(struct ifnet *ifp)
* we're committed to sending it now. if we cant map it into
* dma memory then we drop it.
*/
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
if (vic_load_txb(sc, txb, m) != 0) {
m_freem(m);
ifp->if_oerrors++;
diff --git a/sys/dev/pci/if_vio.c b/sys/dev/pci/if_vio.c
index a844301d6ea..fa15a882002 100644
--- a/sys/dev/pci/if_vio.c
+++ b/sys/dev/pci/if_vio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vio.c,v 1.34 2015/10/25 13:04:28 mpi Exp $ */
+/* $OpenBSD: if_vio.c,v 1.35 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@@ -738,12 +738,13 @@ again:
int slot, r;
struct virtio_net_hdr *hdr;
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break;
r = virtio_enqueue_prep(vq, &slot);
if (r == EAGAIN) {
+ ifq_deq_rollback(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -780,7 +781,7 @@ again:
r = vio_encap(sc, slot, m);
if (r != 0) {
virtio_enqueue_abort(vq, slot);
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
m_freem(m);
ifp->if_oerrors++;
continue;
@@ -790,11 +791,12 @@ again:
if (r != 0) {
bus_dmamap_unload(vsc->sc_dmat,
sc->sc_tx_dmamaps[slot]);
+ ifq_deq_rollback(&ifp->if_snd, m);
sc->sc_tx_mbufs[slot] = NULL;
ifp->if_flags |= IFF_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
bus_dmamap_sync(vsc->sc_dmat, sc->sc_tx_dmamaps[slot], 0,
sc->sc_tx_dmamaps[slot]->dm_mapsize, BUS_DMASYNC_PREWRITE);
diff --git a/sys/dev/pci/if_xge.c b/sys/dev/pci/if_xge.c
index d5e9963ce67..0d277c9af4d 100644
--- a/sys/dev/pci/if_xge.c
+++ b/sys/dev/pci/if_xge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xge.c,v 1.64 2015/11/14 17:54:57 mpi Exp $ */
+/* $OpenBSD: if_xge.c,v 1.65 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_xge.c,v 1.1 2005/09/09 10:30:27 ragge Exp $ */
/*
@@ -1068,23 +1068,26 @@ xge_start(struct ifnet *ifp)
par = lcr = 0;
for (;;) {
- IFQ_POLL(&ifp->if_snd, m);
+ m = ifq_deq_begin(&ifp->if_snd);
if (m == NULL)
break; /* out of packets */
- if (sc->sc_nexttx == sc->sc_lasttx)
+ if (sc->sc_nexttx == sc->sc_lasttx) {
+ ifq_deq_rollback(&ifp->if_snd, m);
break; /* No more space */
+ }
nexttx = sc->sc_nexttx;
dmp = sc->sc_txm[nexttx];
if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmp, m,
BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0) {
+ ifq_deq_rollback(&ifp->if_snd, m);
printf("%s: bus_dmamap_load_mbuf error %d\n",
XNAME, error);
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
+ ifq_deq_commit(&ifp->if_snd, m);
bus_dmamap_sync(sc->sc_dmat, dmp, 0, dmp->dm_mapsize,
BUS_DMASYNC_PREWRITE);
diff --git a/sys/dev/pcmcia/if_malo.c b/sys/dev/pcmcia/if_malo.c
index 75f6e8c27c7..5a98cb117b2 100644
--- a/sys/dev/pcmcia/if_malo.c
+++ b/sys/dev/pcmcia/if_malo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_malo.c,v 1.87 2015/11/11 10:07:25 mpi Exp $ */
+/* $OpenBSD: if_malo.c,v 1.88 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -996,7 +996,6 @@ cmalo_start(struct ifnet *ifp)
if (m == NULL)
return;
-
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
diff --git a/sys/dev/pcmcia/if_xe.c b/sys/dev/pcmcia/if_xe.c
index 96962d764c3..da87735a16c 100644
--- a/sys/dev/pcmcia/if_xe.c
+++ b/sys/dev/pcmcia/if_xe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xe.c,v 1.53 2015/10/25 13:13:06 mpi Exp $ */
+/* $OpenBSD: if_xe.c,v 1.54 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist, Brandon Creighton, Job de Haas
@@ -1090,7 +1090,7 @@ xe_start(ifp)
return;
/* Peek at the next packet. */
- IFQ_POLL(&ifp->if_snd, m0);
+ m0 = ifq_deq_begin(&ifp->if_snd);
if (m0 == NULL)
return;
@@ -1107,13 +1107,14 @@ xe_start(ifp)
PAGE(sc, 0);
space = bus_space_read_2(bst, bsh, offset + TSO0) & 0x7fff;
if (len + pad + 2 > space) {
+ ifq_deq_rollback(&ifp->if_snd, m0);
DPRINTF(XED_FIFO,
("%s: not enough space in output FIFO (%d > %d)\n",
sc->sc_dev.dv_xname, len + pad + 2, space));
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m0);
+ ifq_deq_commit(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
index f65900d2c73..78b906dd237 100644
--- a/sys/dev/usb/if_aue.c
+++ b/sys/dev/usb/if_aue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_aue.c,v 1.101 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_aue.c,v 1.102 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_aue.c,v 1.82 2003/03/05 17:37:36 shiba Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -1244,16 +1244,17 @@ aue_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (aue_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/*
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
index 0f39523f49d..1912c057923 100644
--- a/sys/dev/usb/if_axe.c
+++ b/sys/dev/usb/if_axe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_axe.c,v 1.133 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_axe.c,v 1.134 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org>
@@ -1253,15 +1253,16 @@ axe_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (axe_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
/*
* If there's a BPF listener, bounce a copy of this frame
diff --git a/sys/dev/usb/if_axen.c b/sys/dev/usb/if_axen.c
index 2e84cbe50b5..e02c06bf6fa 100644
--- a/sys/dev/usb/if_axen.c
+++ b/sys/dev/usb/if_axen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_axen.c,v 1.17 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_axen.c,v 1.18 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2013 Yojiro UO <yuo@openbsd.org>
@@ -1273,15 +1273,16 @@ axen_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (axen_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
/*
* If there's a BPF listener, bounce a copy of this frame
diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c
index 596371f65ca..d8435a28d67 100644
--- a/sys/dev/usb/if_cdce.c
+++ b/sys/dev/usb/if_cdce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cdce.c,v 1.66 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_cdce.c,v 1.67 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
@@ -389,16 +389,17 @@ cdce_start(struct ifnet *ifp)
if (usbd_is_dying(sc->cdce_udev) || (ifp->if_flags & IFF_OACTIVE))
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (cdce_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_cdcef.c b/sys/dev/usb/if_cdcef.c
index 8b32dfec7fe..4f3c0a9e9d1 100644
--- a/sys/dev/usb/if_cdcef.c
+++ b/sys/dev/usb/if_cdcef.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cdcef.c,v 1.38 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_cdcef.c,v 1.39 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2007 Dale Rahn <drahn@openbsd.org>
@@ -277,7 +277,7 @@ cdcef_start(struct ifnet *ifp)
if(ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd, m_head);
if (m_head == NULL) {
return;
}
@@ -287,17 +287,18 @@ cdcef_start(struct ifnet *ifp)
* drop packet because receiver is not listening,
* or if packet is larger than xmit buffer
*/
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
m_freem(m_head);
return;
}
if (cdcef_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c
index e4c17ddb7c9..eb85e2bb574 100644
--- a/sys/dev/usb/if_cue.c
+++ b/sys/dev/usb/if_cue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cue.c,v 1.72 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_cue.c,v 1.73 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_cue.c,v 1.40 2002/07/11 21:14:26 augustss Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -887,16 +887,17 @@ cue_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (cue_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/*
diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c
index 5abe5cf9729..d8497babd1a 100644
--- a/sys/dev/usb/if_kue.c
+++ b/sys/dev/usb/if_kue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_kue.c,v 1.81 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_kue.c,v 1.82 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_kue.c,v 1.50 2002/07/16 22:00:31 augustss Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -858,16 +858,17 @@ kue_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (kue_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/*
diff --git a/sys/dev/usb/if_mos.c b/sys/dev/usb/if_mos.c
index 3d41c10a20e..beebf669e71 100644
--- a/sys/dev/usb/if_mos.c
+++ b/sys/dev/usb/if_mos.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mos.c,v 1.32 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_mos.c,v 1.33 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2008 Johann Christian Rode <jcrode@gmx.net>
@@ -1138,15 +1138,16 @@ mos_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (mos_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
/*
* If there's a BPF listener, bounce a copy of this frame
diff --git a/sys/dev/usb/if_smsc.c b/sys/dev/usb/if_smsc.c
index aff4fd8732f..2c812bd70ea 100644
--- a/sys/dev/usb/if_smsc.c
+++ b/sys/dev/usb/if_smsc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_smsc.c,v 1.21 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_smsc.c,v 1.22 2015/11/20 03:35:23 dlg Exp $ */
/* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
/*-
* Copyright (c) 2012
@@ -610,15 +610,16 @@ smsc_start(struct ifnet *ifp)
return;
}
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (smsc_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c
index e4ddd0ad63d..ec0531eba92 100644
--- a/sys/dev/usb/if_udav.c
+++ b/sys/dev/usb/if_udav.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_udav.c,v 1.73 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_udav.c,v 1.74 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_udav.c,v 1.3 2004/04/23 17:25:25 itojun Exp $ */
/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
/*
@@ -918,16 +918,17 @@ udav_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (udav_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_ugl.c b/sys/dev/usb/if_ugl.c
index e7595880f4b..599c8dec796 100644
--- a/sys/dev/usb/if_ugl.c
+++ b/sys/dev/usb/if_ugl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ugl.c,v 1.14 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_ugl.c,v 1.15 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_upl.c,v 1.19 2002/07/11 21:14:26 augustss Exp $ */
/*
* Copyright (c) 2013 SASANO Takayoshi <uaa@uaa.org.uk>
@@ -604,16 +604,17 @@ ugl_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (ugl_send(sc, m_head, 0)) {
+ ifq_deq_commit(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/*
diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c
index 87b37296e9c..2c58fa65fd8 100644
--- a/sys/dev/usb/if_upl.c
+++ b/sys/dev/usb/if_upl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_upl.c,v 1.67 2015/06/30 13:54:42 mpi Exp $ */
+/* $OpenBSD: if_upl.c,v 1.68 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_upl.c,v 1.19 2002/07/11 21:14:26 augustss Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -580,16 +580,17 @@ upl_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (upl_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
/*
diff --git a/sys/dev/usb/if_url.c b/sys/dev/usb/if_url.c
index a9a4cbe113c..a60397df06b 100644
--- a/sys/dev/usb/if_url.c
+++ b/sys/dev/usb/if_url.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_url.c,v 1.76 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_url.c,v 1.77 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_url.c,v 1.6 2002/09/29 10:19:21 martin Exp $ */
/*
* Copyright (c) 2001, 2002
@@ -791,16 +791,17 @@ url_start(struct ifnet *ifp)
if (ifp->if_flags & IFF_OACTIVE)
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (url_send(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
#if NBPFILTER > 0
if (ifp->if_bpf)
diff --git a/sys/dev/usb/if_urndis.c b/sys/dev/usb/if_urndis.c
index 73036bc8ff5..3e6fa3634b8 100644
--- a/sys/dev/usb/if_urndis.c
+++ b/sys/dev/usb/if_urndis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_urndis.c,v 1.56 2015/10/25 12:11:56 mpi Exp $ */
+/* $OpenBSD: if_urndis.c,v 1.57 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2010 Jonathan Armani <armani@openbsd.org>
@@ -1148,15 +1148,16 @@ urndis_start(struct ifnet *ifp)
if (usbd_is_dying(sc->sc_udev) || (ifp->if_flags & IFF_OACTIVE))
return;
- IFQ_POLL(&ifp->if_snd, m_head);
+ m_head = ifq_deq_begin(&ifp->if_snd);
if (m_head == NULL)
return;
if (urndis_encap(sc, m_head, 0)) {
+ ifq_deq_rollback(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
return;
}
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
+ ifq_deq_commit(&ifp->if_snd, m_head);
/*
* If there's a BPF listener, bounce a copy of this frame
diff --git a/sys/net/hfsc.c b/sys/net/hfsc.c
index 1b0f3752c94..05cd4f9e978 100644
--- a/sys/net/hfsc.c
+++ b/sys/net/hfsc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hfsc.c,v 1.30 2015/11/09 01:06:31 dlg Exp $ */
+/* $OpenBSD: hfsc.c,v 1.31 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org>
@@ -181,11 +181,11 @@ struct hfsc_class {
*/
struct hfsc_if {
struct hfsc_if *hif_next; /* interface state list */
- struct ifqueue *hif_ifq; /* backpointer to ifq */
struct hfsc_class *hif_rootclass; /* root class */
struct hfsc_class *hif_defaultclass; /* default class */
struct hfsc_class **hif_class_tbl;
- struct hfsc_class *hif_pollcache; /* cache for poll operation */
+
+ u_int64_t hif_microtime; /* time at deq_begin */
u_int hif_allocated; /* # of slots in hif_class_tbl */
u_int hif_classes; /* # of classes in the tree */
@@ -206,9 +206,8 @@ int hfsc_class_destroy(struct hfsc_if *,
struct hfsc_class *);
struct hfsc_class *hfsc_nextclass(struct hfsc_class *);
-struct mbuf *hfsc_cl_dequeue(struct hfsc_class *);
-struct mbuf *hfsc_cl_poll(struct hfsc_class *);
-void hfsc_cl_purge(struct hfsc_if *, struct hfsc_class *);
+void hfsc_cl_purge(struct hfsc_if *, struct hfsc_class *,
+ struct mbuf_list *);
void hfsc_deferred(void *);
void hfsc_update_cfmin(struct hfsc_class *);
@@ -256,6 +255,30 @@ struct hfsc_class *hfsc_clh2cph(struct hfsc_if *, u_int32_t);
struct pool hfsc_class_pl, hfsc_internal_sc_pl;
+/*
+ * ifqueue glue.
+ */
+
+void *hfsc_alloc(void *);
+void hfsc_free(void *);
+int hfsc_enq(struct ifqueue *, struct mbuf *);
+struct mbuf *hfsc_deq_begin(struct ifqueue *, void **);
+void hfsc_deq_commit(struct ifqueue *, struct mbuf *, void *);
+void hfsc_deq_rollback(struct ifqueue *, struct mbuf *, void *);
+void hfsc_purge(struct ifqueue *, struct mbuf_list *);
+
+const struct ifq_ops hfsc_ops = {
+ hfsc_alloc,
+ hfsc_free,
+ hfsc_enq,
+ hfsc_deq_begin,
+ hfsc_deq_commit,
+ hfsc_deq_rollback,
+ hfsc_purge,
+};
+
+const struct ifq_ops * const ifq_hfsc_ops = &hfsc_ops;
+
u_int64_t
hfsc_microuptime(void)
{
@@ -296,64 +319,37 @@ hfsc_initialize(void)
{
pool_init(&hfsc_class_pl, sizeof(struct hfsc_class), 0, 0, PR_WAITOK,
"hfscclass", NULL);
+ pool_setipl(&hfsc_class_pl, IPL_NONE);
pool_init(&hfsc_internal_sc_pl, sizeof(struct hfsc_internal_sc), 0, 0,
PR_WAITOK, "hfscintsc", NULL);
+ pool_setipl(&hfsc_internal_sc_pl, IPL_NONE);
}
-int
-hfsc_attach(struct ifnet *ifp)
+struct hfsc_if *
+hfsc_pf_alloc(struct ifnet *ifp)
{
struct hfsc_if *hif;
- if (ifp == NULL || ifp->if_snd.ifq_hfsc != NULL)
- return (0);
+ KASSERT(ifp != NULL);
- hif = malloc(sizeof(struct hfsc_if), M_DEVBUF, M_WAITOK | M_ZERO);
+ hif = malloc(sizeof(*hif), M_DEVBUF, M_WAITOK | M_ZERO);
TAILQ_INIT(&hif->hif_eligible);
hif->hif_class_tbl = mallocarray(HFSC_DEFAULT_CLASSES, sizeof(void *),
M_DEVBUF, M_WAITOK | M_ZERO);
hif->hif_allocated = HFSC_DEFAULT_CLASSES;
- hif->hif_ifq = &ifp->if_snd;
- ifp->if_snd.ifq_hfsc = hif;
-
timeout_set(&hif->hif_defer, hfsc_deferred, ifp);
- /* XXX HRTIMER don't schedule it yet, only when some packets wait. */
- timeout_add(&hif->hif_defer, 1);
- return (0);
+ return (hif);
}
int
-hfsc_detach(struct ifnet *ifp)
+hfsc_pf_addqueue(struct hfsc_if *hif, struct pf_queuespec *q)
{
- struct hfsc_if *hif;
-
- if (ifp == NULL)
- return (0);
-
- hif = ifp->if_snd.ifq_hfsc;
- timeout_del(&hif->hif_defer);
- ifp->if_snd.ifq_hfsc = NULL;
-
- free(hif->hif_class_tbl, M_DEVBUF, hif->hif_allocated * sizeof(void *));
- free(hif, M_DEVBUF, sizeof(struct hfsc_if));
-
- return (0);
-}
-
-int
-hfsc_addqueue(struct pf_queuespec *q)
-{
- struct hfsc_if *hif;
struct hfsc_class *cl, *parent;
struct hfsc_sc rtsc, lssc, ulsc;
- if (q->kif->pfik_ifp == NULL)
- return (0);
-
- if ((hif = q->kif->pfik_ifp->if_snd.ifq_hfsc) == NULL)
- return (EINVAL);
+ KASSERT(hif != NULL);
if (q->parent_qid == HFSC_NULLCLASS_HANDLE &&
hif->hif_rootclass == NULL)
@@ -386,61 +382,82 @@ hfsc_addqueue(struct pf_queuespec *q)
}
int
-hfsc_delqueue(struct pf_queuespec *q)
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl;
-
- if (q->kif->pfik_ifp == NULL)
- return (0);
-
- if ((hif = q->kif->pfik_ifp->if_snd.ifq_hfsc) == NULL)
- return (EINVAL);
-
- if ((cl = hfsc_clh2cph(hif, q->qid)) == NULL)
- return (EINVAL);
-
- return (hfsc_class_destroy(hif, cl));
-}
-
-int
-hfsc_qstats(struct pf_queuespec *q, void *ubuf, int *nbytes)
+hfsc_pf_qstats(struct pf_queuespec *q, void *ubuf, int *nbytes)
{
+ struct ifnet *ifp = q->kif->pfik_ifp;
struct hfsc_if *hif;
struct hfsc_class *cl;
struct hfsc_class_stats stats;
int error = 0;
- if (q->kif->pfik_ifp == NULL)
- return (EBADF);
-
- if ((hif = q->kif->pfik_ifp->if_snd.ifq_hfsc) == NULL)
+ if (ifp == NULL)
return (EBADF);
- if ((cl = hfsc_clh2cph(hif, q->qid)) == NULL)
+ if (*nbytes < sizeof(stats))
return (EINVAL);
- if (*nbytes < sizeof(stats))
+ hif = ifq_q_enter(&ifp->if_snd, ifq_hfsc_ops);
+ if (hif == NULL)
+ return (EBADF);
+
+ if ((cl = hfsc_clh2cph(hif, q->qid)) == NULL) {
+ ifq_q_leave(&ifp->if_snd, hif);
return (EINVAL);
+ }
hfsc_getclstats(&stats, cl);
+ ifq_q_leave(&ifp->if_snd, hif);
if ((error = copyout((caddr_t)&stats, ubuf, sizeof(stats))) != 0)
return (error);
+
*nbytes = sizeof(stats);
return (0);
}
void
-hfsc_purge(struct ifqueue *ifq)
+hfsc_pf_free(struct hfsc_if *hif)
+{
+ hfsc_free(hif);
+}
+
+void *
+hfsc_alloc(void *q)
+{
+ struct hfsc_if *hif = q;
+ KASSERT(hif != NULL);
+
+ timeout_add(&hif->hif_defer, 1);
+ return (hif);
+}
+
+void
+hfsc_free(void *q)
{
- struct hfsc_if *hif = ifq->ifq_hfsc;
+ struct hfsc_if *hif = q;
+ int i;
+
+ KERNEL_ASSERT_LOCKED();
+
+ timeout_del(&hif->hif_defer);
+
+ i = hif->hif_allocated;
+ do
+ hfsc_class_destroy(hif, hif->hif_class_tbl[--i]);
+ while (i > 0);
+
+ free(hif->hif_class_tbl, M_DEVBUF, hif->hif_allocated * sizeof(void *));
+ free(hif, M_DEVBUF, sizeof(*hif));
+}
+
+void
+hfsc_purge(struct ifqueue *ifq, struct mbuf_list *ml)
+{
+ struct hfsc_if *hif = ifq->ifq_q;
struct hfsc_class *cl;
for (cl = hif->hif_rootclass; cl != NULL; cl = hfsc_nextclass(cl))
- if (ml_len(&cl->cl_q.q) > 0)
- hfsc_cl_purge(hif, cl);
- hif->hif_ifq->ifq_len = 0;
+ hfsc_cl_purge(hif, cl, ml);
}
struct hfsc_class *
@@ -555,9 +572,7 @@ hfsc_class_destroy(struct hfsc_if *hif, struct hfsc_class *cl)
return (EBUSY);
s = splnet();
-
- if (ml_len(&cl->cl_q.q) > 0)
- hfsc_cl_purge(hif, cl);
+ KASSERT(ml_empty(&cl->cl_q.q));
if (cl->cl_parent != NULL) {
struct hfsc_class *p = cl->cl_parent->cl_children;
@@ -624,9 +639,9 @@ hfsc_nextclass(struct hfsc_class *cl)
}
int
-hfsc_enqueue(struct ifqueue *ifq, struct mbuf *m)
+hfsc_enq(struct ifqueue *ifq, struct mbuf *m)
{
- struct hfsc_if *hif = ifq->ifq_hfsc;
+ struct hfsc_if *hif = ifq->ifq_q;
struct hfsc_class *cl;
if ((cl = hfsc_clh2cph(hif, m->m_pkthdr.pf.qid)) == NULL ||
@@ -638,12 +653,12 @@ hfsc_enqueue(struct ifqueue *ifq, struct mbuf *m)
}
if (ml_len(&cl->cl_q.q) >= cl->cl_q.qlimit) {
- /* drop. mbuf needs to be freed */
+ /* drop occurred. mbuf needs to be freed */
PKTCNTR_INC(&cl->cl_stats.drop_cnt, m->m_pkthdr.len);
return (ENOBUFS);
}
+
ml_enqueue(&cl->cl_q.q, m);
- ifq->ifq_len++;
m->m_pkthdr.pf.prio = IFQ_MAXPRIO;
/* successfully queued. */
@@ -654,71 +669,68 @@ hfsc_enqueue(struct ifqueue *ifq, struct mbuf *m)
}
struct mbuf *
-hfsc_dequeue(struct ifqueue *ifq, int remove)
+hfsc_deq_begin(struct ifqueue *ifq, void **cookiep)
{
- struct hfsc_if *hif = ifq->ifq_hfsc;
+ struct hfsc_if *hif = ifq->ifq_q;
struct hfsc_class *cl, *tcl;
struct mbuf *m;
- int next_len, realtime = 0;
u_int64_t cur_time;
- if (IFQ_LEN(ifq) == 0)
- return (NULL);
-
cur_time = hfsc_microuptime();
- if (remove && hif->hif_pollcache != NULL) {
- cl = hif->hif_pollcache;
- hif->hif_pollcache = NULL;
- /* check if the class was scheduled by real-time criteria */
- if (cl->cl_rsc != NULL)
- realtime = (cl->cl_e <= cur_time);
- } else {
+ /*
+ * if there are eligible classes, use real-time criteria.
+ * find the class with the minimum deadline among
+ * the eligible classes.
+ */
+ cl = hfsc_ellist_get_mindl(hif, cur_time);
+ if (cl == NULL) {
/*
- * if there are eligible classes, use real-time criteria.
- * find the class with the minimum deadline among
- * the eligible classes.
+ * use link-sharing criteria
+ * get the class with the minimum vt in the hierarchy
*/
- if ((cl = hfsc_ellist_get_mindl(hif, cur_time)) != NULL) {
- realtime = 1;
- } else {
+ cl = NULL;
+ tcl = hif->hif_rootclass;
+
+ while (tcl != NULL && tcl->cl_children != NULL) {
+ tcl = hfsc_actlist_firstfit(tcl, cur_time);
+ if (tcl == NULL)
+ continue;
+
/*
- * use link-sharing criteria
- * get the class with the minimum vt in the hierarchy
+ * update parent's cl_cvtmin.
+ * don't update if the new vt is smaller.
*/
- cl = NULL;
- tcl = hif->hif_rootclass;
+ if (tcl->cl_parent->cl_cvtmin < tcl->cl_vt)
+ tcl->cl_parent->cl_cvtmin = tcl->cl_vt;
- while (tcl != NULL && tcl->cl_children != NULL) {
- tcl = hfsc_actlist_firstfit(tcl, cur_time);
- if (tcl == NULL)
- continue;
+ cl = tcl;
+ }
+ /* XXX HRTIMER plan hfsc_deferred precisely here. */
+ if (cl == NULL)
+ return (NULL);
+ }
- /*
- * update parent's cl_cvtmin.
- * don't update if the new vt is smaller.
- */
- if (tcl->cl_parent->cl_cvtmin < tcl->cl_vt)
- tcl->cl_parent->cl_cvtmin = tcl->cl_vt;
+ m = ml_dequeue(&cl->cl_q.q);
+ KASSERT(m != NULL);
- cl = tcl;
- }
- /* XXX HRTIMER plan hfsc_deferred precisely here. */
- if (cl == NULL)
- return (NULL);
- }
+ hif->hif_microtime = cur_time;
+ *cookiep = cl;
+ return (m);
+}
- if (!remove) {
- hif->hif_pollcache = cl;
- m = hfsc_cl_poll(cl);
- return (m);
- }
- }
+void
+hfsc_deq_commit(struct ifqueue *ifq, struct mbuf *m, void *cookie)
+{
+ struct hfsc_if *hif = ifq->ifq_q;
+ struct hfsc_class *cl = cookie;
+ int next_len, realtime = 0;
+ u_int64_t cur_time = hif->hif_microtime;
- if ((m = hfsc_cl_dequeue(cl)) == NULL)
- panic("hfsc_dequeue");
+ /* check if the class was scheduled by real-time criteria */
+ if (cl->cl_rsc != NULL)
+ realtime = (cl->cl_e <= cur_time);
- ifq->ifq_len--;
PKTCNTR_INC(&cl->cl_stats.xmit_cnt, m->m_pkthdr.len);
hfsc_update_vf(cl, m->m_pkthdr.len, cur_time);
@@ -739,51 +751,49 @@ hfsc_dequeue(struct ifqueue *ifq, int remove)
/* the class becomes passive */
hfsc_set_passive(hif, cl);
}
+}
- return (m);
+void
+hfsc_deq_rollback(struct ifqueue *ifq, struct mbuf *m, void *cookie)
+{
+ struct hfsc_class *cl = cookie;
+
+ ml_requeue(&cl->cl_q.q, m);
}
void
hfsc_deferred(void *arg)
{
struct ifnet *ifp = arg;
+ struct hfsc_if *hif;
int s;
+ KERNEL_ASSERT_LOCKED();
+ KASSERT(HFSC_ENABLED(&ifp->if_snd));
+
s = splnet();
- if (HFSC_ENABLED(&ifp->if_snd) && !IFQ_IS_EMPTY(&ifp->if_snd))
+ if (!IFQ_IS_EMPTY(&ifp->if_snd))
if_start(ifp);
splx(s);
- /* XXX HRTIMER nearest virtual/fit time is likely less than 1/HZ. */
- timeout_add(&ifp->if_snd.ifq_hfsc->hif_defer, 1);
-}
-
-struct mbuf *
-hfsc_cl_dequeue(struct hfsc_class *cl)
-{
- return (ml_dequeue(&cl->cl_q.q));
-}
+ hif = ifp->if_snd.ifq_q;
-struct mbuf *
-hfsc_cl_poll(struct hfsc_class *cl)
-{
- /* XXX */
- return (cl->cl_q.q.ml_head);
+ /* XXX HRTIMER nearest virtual/fit time is likely less than 1/HZ. */
+ timeout_add(&hif->hif_defer, 1);
}
void
-hfsc_cl_purge(struct hfsc_if *hif, struct hfsc_class *cl)
+hfsc_cl_purge(struct hfsc_if *hif, struct hfsc_class *cl, struct mbuf_list *ml)
{
struct mbuf *m;
if (ml_empty(&cl->cl_q.q))
return;
- while ((m = hfsc_cl_dequeue(cl)) != NULL) {
+ MBUF_LIST_FOREACH(&cl->cl_q.q, m)
PKTCNTR_INC(&cl->cl_stats.drop_cnt, m->m_pkthdr.len);
- m_freem(m);
- hif->hif_ifq->ifq_len--;
- }
+
+ ml_enlist(ml, &cl->cl_q.q);
hfsc_update_vf(cl, 0, 0); /* remove cl from the actlist */
hfsc_set_passive(hif, cl);
@@ -1544,25 +1554,4 @@ hfsc_clh2cph(struct hfsc_if *hif, u_int32_t chandle)
return (cl);
return (NULL);
}
-
-#else /* NPF > 0 */
-
-void
-hfsc_purge(struct ifqueue *q)
-{
- panic("hfsc_purge called on hfsc-less kernel");
-}
-
-int
-hfsc_enqueue(struct ifqueue *q, struct mbuf *m)
-{
- panic("hfsc_enqueue called on hfsc-less kernel");
-}
-
-struct mbuf *
-hfsc_dequeue(struct ifqueue *q, int i)
-{
- panic("hfsc_enqueue called on hfsc-less kernel");
-}
-
#endif
diff --git a/sys/net/hfsc.h b/sys/net/hfsc.h
index ae746e50ad0..544d9df6259 100644
--- a/sys/net/hfsc.h
+++ b/sys/net/hfsc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hfsc.h,v 1.10 2015/11/09 01:06:31 dlg Exp $ */
+/* $OpenBSD: hfsc.h,v 1.11 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org>
@@ -112,19 +112,18 @@ struct ifqueue;
struct pf_queuespec;
struct hfsc_if;
-#define HFSC_ENABLED(ifq) ((ifq)->ifq_hfsc != NULL)
+extern const struct ifq_ops * const ifq_hfsc_ops;
+
+#define HFSC_ENABLED(ifq) ((ifq)->ifq_ops == ifq_hfsc_ops)
#define HFSC_DEFAULT_QLIMIT 50
+struct hfsc_if *hfsc_pf_alloc(struct ifnet *);
+int hfsc_pf_addqueue(struct hfsc_if *, struct pf_queuespec *);
+void hfsc_pf_free(struct hfsc_if *);
+int hfsc_pf_qstats(struct pf_queuespec *, void *, int *);
+
void hfsc_initialize(void);
-int hfsc_attach(struct ifnet *);
-int hfsc_detach(struct ifnet *);
-void hfsc_purge(struct ifqueue *);
-int hfsc_enqueue(struct ifqueue *, struct mbuf *);
-struct mbuf *hfsc_dequeue(struct ifqueue *, int);
u_int64_t hfsc_microuptime(void);
-int hfsc_addqueue(struct pf_queuespec *);
-int hfsc_delqueue(struct pf_queuespec *);
-int hfsc_qstats(struct pf_queuespec *, void *, int *);
#endif /* _KERNEL */
#endif /* _HFSC_H_ */
diff --git a/sys/net/if.c b/sys/net/if.c
index 2f4d0399f6f..75b3e96b7f8 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.407 2015/11/18 13:58:02 mpi Exp $ */
+/* $OpenBSD: if.c,v 1.408 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -397,9 +397,6 @@ if_attachsetup(struct ifnet *ifp)
if_addgroup(ifp, IFG_ALL);
- if (ifp->if_snd.ifq_maxlen == 0)
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
-
if_attachdomain(ifp);
#if NPF > 0
pfi_attach_ifnet(ifp);
@@ -510,6 +507,8 @@ if_attach_common(struct ifnet *ifp)
TAILQ_INIT(&ifp->if_addrlist);
TAILQ_INIT(&ifp->if_maddrlist);
+ ifq_init(&ifp->if_snd);
+
ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
M_TEMP, M_WAITOK);
TAILQ_INIT(ifp->if_addrhooks);
@@ -538,7 +537,7 @@ if_start(struct ifnet *ifp)
splassert(IPL_NET);
- if (ifp->if_snd.ifq_len >= min(8, ifp->if_snd.ifq_maxlen) &&
+ if (ifq_len(&ifp->if_snd) >= min(8, ifp->if_snd.ifq_maxlen) &&
!ISSET(ifp->if_flags, IFF_OACTIVE)) {
if (ISSET(ifp->if_xflags, IFXF_TXREADY)) {
TAILQ_REMOVE(&iftxlist, ifp, if_txlist);
@@ -783,8 +782,6 @@ if_input_process(void *xmq)
s = splnet();
while ((m = ml_dequeue(&ml)) != NULL) {
- sched_pause();
-
ifp = if_get(m->m_pkthdr.ph_ifidx);
if (ifp == NULL) {
m_freem(m);
@@ -942,6 +939,8 @@ if_detach(struct ifnet *ifp)
if_idxmap_remove(ifp);
splx(s);
+
+ ifq_destroy(&ifp->if_snd);
}
/*
@@ -2725,6 +2724,327 @@ niq_enlist(struct niqueue *niq, struct mbuf_list *ml)
return (rv);
}
+/*
+ * send queues.
+ */
+
+void *priq_alloc(void *);
+void priq_free(void *);
+int priq_enq(struct ifqueue *, struct mbuf *);
+struct mbuf *priq_deq_begin(struct ifqueue *, void **);
+void priq_deq_commit(struct ifqueue *, struct mbuf *, void *);
+void priq_deq_rollback(struct ifqueue *, struct mbuf *, void *);
+void priq_purge(struct ifqueue *, struct mbuf_list *);
+
+const struct ifq_ops priq_ops = {
+ priq_alloc,
+ priq_free,
+ priq_enq,
+ priq_deq_begin,
+ priq_deq_commit,
+ priq_deq_rollback,
+ priq_purge,
+};
+
+const struct ifq_ops * const ifq_priq_ops = &priq_ops;
+
+struct priq_list {
+ struct mbuf *head;
+ struct mbuf *tail;
+};
+
+struct priq {
+ struct priq_list pq_lists[IFQ_NQUEUES];
+};
+
+void *
+priq_alloc(void *null)
+{
+ return (malloc(sizeof(struct priq), M_DEVBUF, M_WAITOK | M_ZERO));
+}
+
+void
+priq_free(void *pq)
+{
+ free(pq, M_DEVBUF, sizeof(struct priq));
+}
+
+int
+priq_enq(struct ifqueue *ifq, struct mbuf *m)
+{
+ struct priq *pq;
+ struct priq_list *pl;
+
+ if (ifq_len(ifq) >= ifq->ifq_maxlen)
+ return (ENOBUFS);
+
+ pq = ifq->ifq_q;
+ KASSERT(m->m_pkthdr.pf.prio < IFQ_MAXPRIO);
+ pl = &pq->pq_lists[m->m_pkthdr.pf.prio];
+
+ m->m_nextpkt = NULL;
+ if (pl->tail == NULL)
+ pl->head = m;
+ else
+ pl->tail->m_nextpkt = m;
+ pl->tail = m;
+
+ return (0);
+}
+
+struct mbuf *
+priq_deq_begin(struct ifqueue *ifq, void **cookiep)
+{
+ struct priq *pq = ifq->ifq_q;
+ struct priq_list *pl;
+ unsigned int prio = nitems(pq->pq_lists);
+ struct mbuf *m;
+
+ do {
+ pl = &pq->pq_lists[--prio];
+ m = pl->head;
+ if (m != NULL) {
+ *cookiep = pl;
+ return (m);
+ }
+ } while (prio > 0);
+
+ return (NULL);
+}
+
+void
+priq_deq_commit(struct ifqueue *ifq, struct mbuf *m, void *cookie)
+{
+ struct priq_list *pl = cookie;
+
+ KASSERT(pl->head == m);
+
+ pl->head = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+
+ if (pl->head == NULL)
+ pl->tail = NULL;
+}
+
+void
+priq_deq_rollback(struct ifqueue *ifq, struct mbuf *m, void *cookie)
+{
+#ifdef DIAGNOSTIC
+ struct priq_list *pl = cookie;
+
+ KASSERT(pl->head == m);
+#endif
+}
+
+void
+priq_purge(struct ifqueue *ifq, struct mbuf_list *ml)
+{
+ struct priq *pq = ifq->ifq_q;
+ struct priq_list *pl;
+ unsigned int prio = nitems(pq->pq_lists);
+ struct mbuf *m, *n;
+
+ do {
+ pl = &pq->pq_lists[--prio];
+
+ for (m = pl->head; m != NULL; m = n) {
+ n = m->m_nextpkt;
+ ml_enqueue(ml, m);
+ }
+
+ pl->head = pl->tail = NULL;
+ } while (prio > 0);
+}
+
+int
+ifq_enqueue_try(struct ifqueue *ifq, struct mbuf *m)
+{
+ int rv;
+
+ mtx_enter(&ifq->ifq_mtx);
+ rv = ifq->ifq_ops->ifqop_enq(ifq, m);
+ if (rv == 0)
+ ifq->ifq_len++;
+ else
+ ifq->ifq_drops++;
+ mtx_leave(&ifq->ifq_mtx);
+
+ return (rv);
+}
+
+int
+ifq_enq(struct ifqueue *ifq, struct mbuf *m)
+{
+ int err;
+
+ err = ifq_enqueue_try(ifq, m);
+ if (err != 0)
+ m_freem(m);
+
+ return (err);
+}
+
+struct mbuf *
+ifq_deq_begin(struct ifqueue *ifq)
+{
+ struct mbuf *m = NULL;
+ void *cookie;
+
+ mtx_enter(&ifq->ifq_mtx);
+ if (ifq->ifq_len == 0 ||
+ (m = ifq->ifq_ops->ifqop_deq_begin(ifq, &cookie)) == NULL) {
+ mtx_leave(&ifq->ifq_mtx);
+ return (NULL);
+ }
+
+ m->m_pkthdr.ph_cookie = cookie;
+
+ return (m);
+}
+
+void
+ifq_deq_commit(struct ifqueue *ifq, struct mbuf *m)
+{
+ void *cookie;
+
+ KASSERT(m != NULL);
+ cookie = m->m_pkthdr.ph_cookie;
+
+ ifq->ifq_ops->ifqop_deq_commit(ifq, m, cookie);
+ ifq->ifq_len--;
+ mtx_leave(&ifq->ifq_mtx);
+}
+
+void
+ifq_deq_rollback(struct ifqueue *ifq, struct mbuf *m)
+{
+ void *cookie;
+
+ KASSERT(m != NULL);
+ cookie = m->m_pkthdr.ph_cookie;
+
+ ifq->ifq_ops->ifqop_deq_rollback(ifq, m, cookie);
+ mtx_leave(&ifq->ifq_mtx);
+}
+
+struct mbuf *
+ifq_deq(struct ifqueue *ifq)
+{
+ struct mbuf *m;
+
+ m = ifq_deq_begin(ifq);
+ if (m == NULL)
+ return (NULL);
+
+ ifq_deq_commit(ifq, m);
+
+ return (m);
+}
+
+unsigned int
+ifq_purge(struct ifqueue *ifq)
+{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ unsigned int rv;
+
+ mtx_enter(&ifq->ifq_mtx);
+ ifq->ifq_ops->ifqop_purge(ifq, &ml);
+ rv = ifq->ifq_len;
+ ifq->ifq_len = 0;
+ ifq->ifq_drops += rv;
+ mtx_leave(&ifq->ifq_mtx);
+
+ KASSERT(rv == ml_len(&ml));
+
+ ml_purge(&ml);
+
+ return (rv);
+}
+
+void
+ifq_init(struct ifqueue *ifq)
+{
+ mtx_init(&ifq->ifq_mtx, IPL_NET);
+ ifq->ifq_drops = 0;
+
+ /* default to priq */
+ ifq->ifq_ops = &priq_ops;
+ ifq->ifq_q = priq_ops.ifqop_alloc(NULL);
+
+ ifq->ifq_serializer = 0;
+ ifq->ifq_len = 0;
+
+ if (ifq->ifq_maxlen == 0)
+ ifq_set_maxlen(ifq, IFQ_MAXLEN);
+}
+
+void
+ifq_attach(struct ifqueue *ifq, const struct ifq_ops *newops, void *opsarg)
+{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct mbuf_list free_ml = MBUF_LIST_INITIALIZER();
+ struct mbuf *m;
+ const struct ifq_ops *oldops;
+ void *newq, *oldq;
+
+ newq = newops->ifqop_alloc(opsarg);
+
+ mtx_enter(&ifq->ifq_mtx);
+ ifq->ifq_ops->ifqop_purge(ifq, &ml);
+ ifq->ifq_len = 0;
+
+ oldops = ifq->ifq_ops;
+ oldq = ifq->ifq_q;
+
+ ifq->ifq_ops = newops;
+ ifq->ifq_q = newq;
+
+ while ((m = ml_dequeue(&ml)) != NULL) {
+ if (ifq->ifq_ops->ifqop_enq(ifq, m) != 0) {
+ ifq->ifq_drops++;
+ ml_enqueue(&free_ml, m);
+ } else
+ ifq->ifq_len++;
+ }
+ mtx_leave(&ifq->ifq_mtx);
+
+ oldops->ifqop_free(oldq);
+
+ ml_purge(&free_ml);
+}
+
+void *
+ifq_q_enter(struct ifqueue *ifq, const struct ifq_ops *ops)
+{
+ mtx_enter(&ifq->ifq_mtx);
+ if (ifq->ifq_ops == ops)
+ return (ifq->ifq_q);
+
+ mtx_leave(&ifq->ifq_mtx);
+
+ return (NULL);
+}
+
+void
+ifq_q_leave(struct ifqueue *ifq, void *q)
+{
+ KASSERT(q == ifq->ifq_q);
+ mtx_leave(&ifq->ifq_mtx);
+}
+
+void
+ifq_destroy(struct ifqueue *ifq)
+{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+
+ /* don't need to lock because this is the last use of the ifq */
+
+ ifq->ifq_ops->ifqop_purge(ifq, &ml);
+ ifq->ifq_ops->ifqop_free(ifq->ifq_q);
+
+ ml_purge(&ml);
+}
+
__dead void
unhandled_af(int af)
{
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index 6f0dff68a9d..948a0f0f296 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tun.c,v 1.159 2015/10/25 12:05:40 mpi Exp $ */
+/* $OpenBSD: if_tun.c,v 1.160 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
/*
@@ -685,10 +685,11 @@ tun_dev_ioctl(struct tun_softc *tp, u_long cmd, caddr_t data, int flag,
tp->tun_flags &= ~TUN_ASYNC;
break;
case FIONREAD:
- IFQ_POLL(&tp->tun_if.if_snd, m);
- if (m != NULL)
+ m = ifq_deq_begin(&tp->tun_if.if_snd);
+ if (m != NULL) {
*(int *)data = m->m_pkthdr.len;
- else
+ ifq_deq_rollback(&tp->tun_if.if_snd, m);
+ } else
*(int *)data = 0;
break;
case TIOCSPGRP:
@@ -810,6 +811,14 @@ tun_dev_read(struct tun_softc *tp, struct uio *uio, int ioflag)
} while (m0 == NULL);
splx(s);
+ if (tp->tun_flags & TUN_LAYER2) {
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ ifp->if_opackets++;
+ }
+
while (m0 != NULL && uio->uio_resid > 0 && error == 0) {
len = min(uio->uio_resid, m0->m_len);
if (len != 0)
@@ -1007,7 +1016,7 @@ tun_dev_poll(struct tun_softc *tp, int events, struct proc *p)
{
int revents, s;
struct ifnet *ifp;
- struct mbuf *m;
+ unsigned int len;
ifp = &tp->tun_if;
revents = 0;
@@ -1015,10 +1024,9 @@ tun_dev_poll(struct tun_softc *tp, int events, struct proc *p)
TUNDEBUG(("%s: tunpoll\n", ifp->if_xname));
if (events & (POLLIN | POLLRDNORM)) {
- IFQ_POLL(&ifp->if_snd, m);
- if (m != NULL) {
- TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname,
- IFQ_LEN(ifp->if_snd)));
+ len = IFQ_LEN(&ifp->if_snd);
+ if (len > 0) {
+ TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname, len));
revents |= events & (POLLIN | POLLRDNORM);
} else {
TUNDEBUG(("%s: tunpoll waiting\n", ifp->if_xname));
@@ -1114,7 +1122,7 @@ filt_tunread(struct knote *kn, long hint)
int s;
struct tun_softc *tp;
struct ifnet *ifp;
- struct mbuf *m;
+ unsigned int len;
if (kn->kn_status & KN_DETACHED) {
kn->kn_data = 0;
@@ -1125,10 +1133,10 @@ filt_tunread(struct knote *kn, long hint)
ifp = &tp->tun_if;
s = splnet();
- IFQ_POLL(&ifp->if_snd, m);
- if (m != NULL) {
+ len = IFQ_LEN(&ifp->if_snd);
+ if (len > 0) {
splx(s);
- kn->kn_data = IFQ_LEN(&ifp->if_snd);
+ kn->kn_data = len;
TUNDEBUG(("%s: tunkqread q=%d\n", ifp->if_xname,
IFQ_LEN(&ifp->if_snd)));
@@ -1175,21 +1183,11 @@ void
tun_start(struct ifnet *ifp)
{
struct tun_softc *tp = ifp->if_softc;
- struct mbuf *m;
splassert(IPL_NET);
- IFQ_POLL(&ifp->if_snd, m);
- if (m != NULL) {
- if (tp->tun_flags & TUN_LAYER2) {
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
-#endif
- ifp->if_opackets++;
- }
+ if (IFQ_LEN(&ifp->if_snd))
tun_wakeup(tp);
- }
}
void
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index abc6af69dbc..470e5543f99 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_var.h,v 1.53 2015/11/18 13:58:02 mpi Exp $ */
+/* $OpenBSD: if_var.h,v 1.54 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -98,17 +98,33 @@ struct if_clone {
{ { 0 }, name, sizeof(name) - 1, create, destroy }
/*
- * Structure defining a queue for a network interface.
+ * Structure defining the send queue for a network interface.
*/
-struct ifqueue {
- struct {
- struct mbuf *head;
- struct mbuf *tail;
- } ifq_q[IFQ_NQUEUES];
- int ifq_len;
- int ifq_maxlen;
- int ifq_drops;
- struct hfsc_if *ifq_hfsc;
+
+struct ifqueue;
+
+struct ifq_ops {
+ void *(*ifqop_alloc)(void *);
+ void (*ifqop_free)(void *);
+ int (*ifqop_enq)(struct ifqueue *, struct mbuf *);
+ struct mbuf *(*ifqop_deq_begin)(struct ifqueue *, void **);
+ void (*ifqop_deq_commit)(struct ifqueue *,
+ struct mbuf *, void *);
+ void (*ifqop_deq_rollback)(struct ifqueue *,
+ struct mbuf *, void *);
+ void (*ifqop_purge)(struct ifqueue *,
+ struct mbuf_list *);
+};
+
+struct ifqueue {
+ struct mutex ifq_mtx;
+ uint64_t ifq_drops;
+ const struct ifq_ops *ifq_ops;
+ void *ifq_q;
+ unsigned int ifq_len;
+ unsigned int ifq_serializer;
+
+ unsigned int ifq_maxlen;
};
/*
@@ -256,121 +272,55 @@ struct ifg_list {
};
#ifdef _KERNEL
-#define IFQ_MAXLEN 256
-#define IFNET_SLOWHZ 1 /* granularity is 1 second */
-
/*
- * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
- * input routines have queues of messages stored on ifqueue structures
- * (defined above). Entries are added to and deleted from these structures
- * by these macros, which should be called with ipl raised to splnet().
+ * Interface send queues.
*/
-#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
-#define IF_DROP(ifq) ((ifq)->ifq_drops++)
-#define IF_ENQUEUE(ifq, m) \
-do { \
- (m)->m_nextpkt = NULL; \
- if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL) \
- (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = m; \
- else \
- (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail->m_nextpkt = m; \
- (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = m; \
- (ifq)->ifq_len++; \
-} while (/* CONSTCOND */0)
-#define IF_PREPEND(ifq, m) \
-do { \
- (m)->m_nextpkt = (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head; \
- if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL) \
- (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = (m); \
- (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = (m); \
- (ifq)->ifq_len++; \
-} while (/* CONSTCOND */0)
-#define IF_POLL(ifq, m) \
-do { \
- int if_dequeue_prio = IFQ_MAXPRIO; \
- do { \
- (m) = (ifq)->ifq_q[if_dequeue_prio].head; \
- } while (!(m) && --if_dequeue_prio >= 0); \
-} while (/* CONSTCOND */0)
+void ifq_init(struct ifqueue *);
+void ifq_attach(struct ifqueue *, const struct ifq_ops *, void *);
+void ifq_destroy(struct ifqueue *);
+int ifq_enq_try(struct ifqueue *, struct mbuf *);
+int ifq_enq(struct ifqueue *, struct mbuf *);
+struct mbuf *ifq_deq_begin(struct ifqueue *);
+void ifq_deq_commit(struct ifqueue *, struct mbuf *);
+void ifq_deq_rollback(struct ifqueue *, struct mbuf *);
+struct mbuf *ifq_deq(struct ifqueue *);
+unsigned int ifq_purge(struct ifqueue *);
+void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *);
+void ifq_q_leave(struct ifqueue *, void *);
+
+#define ifq_len(_ifq) ((_ifq)->ifq_len)
+#define ifq_empty(_ifq) (ifq_len(_ifq) == 0)
+#define ifq_set_maxlen(_ifq, _l) ((_ifq)->ifq_maxlen = (_l))
+
+extern const struct ifq_ops * const ifq_priq_ops;
-#define IF_DEQUEUE(ifq, m) \
-do { \
- int if_dequeue_prio = IFQ_MAXPRIO; \
- do { \
- (m) = (ifq)->ifq_q[if_dequeue_prio].head; \
- if (m) { \
- if (((ifq)->ifq_q[if_dequeue_prio].head = \
- (m)->m_nextpkt) == NULL) \
- (ifq)->ifq_q[if_dequeue_prio].tail = NULL; \
- (m)->m_nextpkt = NULL; \
- (ifq)->ifq_len--; \
- } \
- } while (!(m) && --if_dequeue_prio >= 0); \
-} while (/* CONSTCOND */0)
+#define IFQ_MAXLEN 256
+#define IFNET_SLOWHZ 1 /* granularity is 1 second */
-#define IF_PURGE(ifq) \
-do { \
- struct mbuf *__m0; \
- \
- for (;;) { \
- IF_DEQUEUE((ifq), __m0); \
- if (__m0 == NULL) \
- break; \
- else \
- m_freem(__m0); \
- } \
-} while (/* CONSTCOND */0)
-#define IF_LEN(ifq) ((ifq)->ifq_len)
-#define IF_IS_EMPTY(ifq) ((ifq)->ifq_len == 0)
+/*
+ * IFQ compat on ifq API
+ */
#define IFQ_ENQUEUE(ifq, m, err) \
do { \
- if (HFSC_ENABLED(ifq)) \
- (err) = hfsc_enqueue(((struct ifqueue *)(ifq)), m); \
- else { \
- if (IF_QFULL((ifq))) { \
- (err) = ENOBUFS; \
- } else { \
- IF_ENQUEUE((ifq), (m)); \
- (err) = 0; \
- } \
- } \
- if ((err)) { \
- m_freem((m)); \
- (ifq)->ifq_drops++; \
- } \
+ (err) = ifq_enq((ifq), (m)); \
} while (/* CONSTCOND */0)
#define IFQ_DEQUEUE(ifq, m) \
do { \
- if (HFSC_ENABLED((ifq))) \
- (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 1); \
- else \
- IF_DEQUEUE((ifq), (m)); \
-} while (/* CONSTCOND */0)
-
-#define IFQ_POLL(ifq, m) \
-do { \
- if (HFSC_ENABLED((ifq))) \
- (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 0); \
- else \
- IF_POLL((ifq), (m)); \
+ (m) = ifq_deq(ifq); \
} while (/* CONSTCOND */0)
#define IFQ_PURGE(ifq) \
do { \
- if (HFSC_ENABLED((ifq))) \
- hfsc_purge(((struct ifqueue *)(ifq))); \
- else \
- IF_PURGE((ifq)); \
+ (void)ifq_purge(ifq); \
} while (/* CONSTCOND */0)
-#define IFQ_SET_READY(ifq) /* nothing */
-
-#define IFQ_LEN(ifq) IF_LEN(ifq)
-#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0)
-#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len))
+#define IFQ_LEN(ifq) ifq_len(ifq)
+#define IFQ_IS_EMPTY(ifq) ifq_empty(ifq)
+#define IFQ_SET_MAXLEN(ifq, len) ifq_set_maxlen(ifq, len)
+#define IFQ_SET_READY(ifq) do { } while (0)
/* default interface priorities */
#define IF_WIRED_DEFAULT_PRIORITY 0
@@ -405,6 +355,7 @@ extern struct ifnet_head ifnet;
extern unsigned int lo0ifidx;
void if_start(struct ifnet *);
+int if_enqueue_try(struct ifnet *, struct mbuf *);
int if_enqueue(struct ifnet *, struct mbuf *);
void if_input(struct ifnet *, struct mbuf_list *);
int if_input_local(struct ifnet *, struct mbuf *, sa_family_t);
diff --git a/sys/net/pf_if.c b/sys/net/pf_if.c
index 25bf59347d6..fdef0783f43 100644
--- a/sys/net/pf_if.c
+++ b/sys/net/pf_if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_if.c,v 1.81 2015/10/30 11:33:55 mikeb Exp $ */
+/* $OpenBSD: pf_if.c,v 1.82 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright 2005 Henning Brauer <henning@openbsd.org>
@@ -258,11 +258,6 @@ pfi_detach_ifnet(struct ifnet *ifp)
hook_disestablish(ifp->if_addrhooks, kif->pfik_ah_cookie);
pfi_kif_update(kif);
- if (HFSC_ENABLED(&ifp->if_snd)) {
- pf_remove_queues(ifp);
- pf_free_queues(pf_queues_active, ifp);
- }
-
kif->pfik_ifp = NULL;
ifp->if_pf_kif = NULL;
pfi_kif_unref(kif, PFI_KIF_REF_NONE);
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 0709b8fb9ed..7d8d74f2435 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.291 2015/10/13 19:32:31 sashan Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.292 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -85,8 +85,10 @@ int pfclose(dev_t, int, int, struct proc *);
int pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
int pf_begin_rules(u_int32_t *, const char *);
int pf_rollback_rules(u_int32_t, char *);
-int pf_create_queues(void);
+int pf_enable_queues(void);
+void pf_remove_queues(void);
int pf_commit_queues(void);
+void pf_free_queues(struct pf_queuehead *);
int pf_setup_pfsync_matching(struct pf_ruleset *);
void pf_hash_rule(MD5_CTX *, struct pf_rule *);
void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
@@ -517,68 +519,144 @@ pf_rollback_rules(u_int32_t ticket, char *anchor)
/* queue defs only in the main ruleset */
if (anchor[0])
return (0);
- return (pf_free_queues(pf_queues_inactive, NULL));
+
+ pf_free_queues(pf_queues_inactive);
+
+ return (0);
}
-int
-pf_free_queues(struct pf_queuehead *where, struct ifnet *ifp)
+void
+pf_free_queues(struct pf_queuehead *where)
{
struct pf_queuespec *q, *qtmp;
TAILQ_FOREACH_SAFE(q, where, entries, qtmp) {
- if (ifp && q->kif->pfik_ifp != ifp)
- continue;
TAILQ_REMOVE(where, q, entries);
pfi_kif_unref(q->kif, PFI_KIF_REF_RULE);
pool_put(&pf_queue_pl, q);
}
- return (0);
}
-int
-pf_remove_queues(struct ifnet *ifp)
+void
+pf_remove_queues(void)
{
struct pf_queuespec *q;
- int error = 0;
-
- /* remove queues */
- TAILQ_FOREACH_REVERSE(q, pf_queues_active, pf_queuehead, entries) {
- if (ifp && q->kif->pfik_ifp != ifp)
- continue;
- if ((error = hfsc_delqueue(q)) != 0)
- return (error);
- }
+ struct ifnet *ifp;
/* put back interfaces in normal queueing mode */
TAILQ_FOREACH(q, pf_queues_active, entries) {
- if (ifp && q->kif->pfik_ifp != ifp)
+ if (q->parent_qid != 0)
+ continue;
+
+ ifp = q->kif->pfik_ifp;
+ if (ifp == NULL)
continue;
- if (q->parent_qid == 0)
- if ((error = hfsc_detach(q->kif->pfik_ifp)) != 0)
- return (error);
+
+ KASSERT(HFSC_ENABLED(&ifp->if_snd));
+
+ ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL);
}
+}
- return (0);
+struct pf_hfsc_queue {
+ struct ifnet *ifp;
+ struct hfsc_if *hif;
+ struct pf_hfsc_queue *next;
+};
+
+static inline struct pf_hfsc_queue *
+pf_hfsc_ifp2q(struct pf_hfsc_queue *list, struct ifnet *ifp)
+{
+ struct pf_hfsc_queue *phq = list;
+
+ while (phq != NULL) {
+ if (phq->ifp == ifp)
+ return (phq);
+
+ phq = phq->next;
+ }
+
+ return (phq);
}
int
pf_create_queues(void)
{
struct pf_queuespec *q;
- int error = 0;
+ struct ifnet *ifp;
+ struct pf_hfsc_queue *list = NULL, *phq;
+ int error;
+
+ /* find root queues and alloc hfsc for these interfaces */
+ TAILQ_FOREACH(q, pf_queues_active, entries) {
+ if (q->parent_qid != 0)
+ continue;
+
+ ifp = q->kif->pfik_ifp;
+ if (ifp == NULL)
+ continue;
+
+ phq = malloc(sizeof(*phq), M_TEMP, M_WAITOK);
+ phq->ifp = ifp;
+ phq->hif = hfsc_pf_alloc(ifp);
- /* find root queues and attach hfsc to these interfaces */
- TAILQ_FOREACH(q, pf_queues_active, entries)
- if (q->parent_qid == 0)
- if ((error = hfsc_attach(q->kif->pfik_ifp)) != 0)
- return (error);
+ phq->next = list;
+ list = phq;
+ }
/* and now everything */
- TAILQ_FOREACH(q, pf_queues_active, entries)
- if ((error = hfsc_addqueue(q)) != 0)
- return (error);
+ TAILQ_FOREACH(q, pf_queues_active, entries) {
+ ifp = q->kif->pfik_ifp;
+ if (ifp == NULL)
+ continue;
+
+ phq = pf_hfsc_ifp2q(list, ifp);
+ KASSERT(phq != NULL);
+
+ error = hfsc_pf_addqueue(phq->hif, q);
+ if (error != 0)
+ goto error;
+ }
+
+ /* find root queues in old list to disable them if necessary */
+ TAILQ_FOREACH(q, pf_queues_inactive, entries) {
+ if (q->parent_qid != 0)
+ continue;
+
+ ifp = q->kif->pfik_ifp;
+ if (ifp == NULL)
+ continue;
+
+ phq = pf_hfsc_ifp2q(list, ifp);
+ if (phq != NULL)
+ continue;
+
+ ifq_attach(&ifp->if_snd, ifq_priq_ops, NULL);
+ }
+
+ /* commit the new queues */
+ while (list != NULL) {
+ phq = list;
+ list = phq->next;
+
+ ifp = phq->ifp;
+
+ ifq_attach(&ifp->if_snd, ifq_hfsc_ops, phq->hif);
+ free(phq, M_TEMP, sizeof(*phq));
+ }
return (0);
+
+error:
+ while (list != NULL) {
+ phq = list;
+ list = phq->next;
+
+ hfsc_pf_free(phq->hif);
+ free(phq, M_TEMP, sizeof(*phq));
+ }
+
+ return (error);
}
int
@@ -587,16 +665,21 @@ pf_commit_queues(void)
struct pf_queuehead *qswap;
int error;
- if ((error = pf_remove_queues(NULL)) != 0)
+ /* swap */
+ qswap = pf_queues_active;
+ pf_queues_active = pf_queues_inactive;
+ pf_queues_inactive = qswap;
+
+ error = pf_create_queues();
+ if (error != 0) {
+ pf_queues_inactive = pf_queues_active;
+ pf_queues_active = qswap;
return (error);
+ }
- /* swap */
- qswap = pf_queues_active;
- pf_queues_active = pf_queues_inactive;
- pf_queues_inactive = qswap;
- pf_free_queues(pf_queues_inactive, NULL);
+ pf_free_queues(pf_queues_inactive);
- return (pf_create_queues());
+ return (0);
}
#define PF_MD5_UPD(st, elm) \
@@ -935,7 +1018,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
else {
pf_status.running = 0;
pf_status.since = time_second;
- pf_remove_queues(NULL);
+ pf_remove_queues();
DPFPRINTF(LOG_NOTICE, "pf: stopped");
}
break;
@@ -1001,7 +1084,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
bcopy(qs, &pq->queue, sizeof(pq->queue));
- error = hfsc_qstats(qs, pq->buf, &nbytes);
+ error = hfsc_pf_qstats(qs, pq->buf, &nbytes);
if (error == 0)
pq->nbytes = nbytes;
break;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index aad10865ed3..5c5a30e3879 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.422 2015/10/30 11:33:55 mikeb Exp $ */
+/* $OpenBSD: pfvar.h,v 1.423 2015/11/20 03:35:23 dlg Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1657,9 +1657,6 @@ extern struct pf_queuehead pf_queues[2];
extern struct pf_queuehead *pf_queues_active, *pf_queues_inactive;
extern u_int32_t ticket_pabuf;
-extern int pf_free_queues(struct pf_queuehead *,
- struct ifnet *);
-extern int pf_remove_queues(struct ifnet *);
extern int pf_tbladdr_setup(struct pf_ruleset *,
struct pf_addr_wrap *);
extern void pf_tbladdr_remove(struct pf_addr_wrap *);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index f1f43ff8003..81bcdddacc5 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbuf.h,v 1.202 2015/11/13 10:12:39 mpi Exp $ */
+/* $OpenBSD: mbuf.h,v 1.203 2015/11/20 03:35:23 dlg Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@@ -392,6 +392,21 @@ struct mbstat {
u_short m_mtypes[256]; /* type specific mbuf allocations */
};
+#include <sys/mutex.h>
+
+struct mbuf_list {
+ struct mbuf *ml_head;
+ struct mbuf *ml_tail;
+ u_int ml_len;
+};
+
+struct mbuf_queue {
+ struct mutex mq_mtx;
+ struct mbuf_list mq_list;
+ u_int mq_maxlen;
+ u_int mq_drops;
+};
+
#ifdef _KERNEL
extern struct mbstat mbstat;
@@ -474,14 +489,6 @@ struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
* mbuf lists
*/
-#include <sys/mutex.h>
-
-struct mbuf_list {
- struct mbuf *ml_head;
- struct mbuf *ml_tail;
- u_int ml_len;
-};
-
#define MBUF_LIST_INITIALIZER() { NULL, NULL, 0 }
void ml_init(struct mbuf_list *);
@@ -504,13 +511,6 @@ unsigned int ml_purge(struct mbuf_list *);
* mbuf queues
*/
-struct mbuf_queue {
- struct mutex mq_mtx;
- struct mbuf_list mq_list;
- u_int mq_maxlen;
- u_int mq_drops;
-};
-
#define MBUF_QUEUE_INITIALIZER(_maxlen, _ipl) \
{ MUTEX_INITIALIZER(_ipl), MBUF_LIST_INITIALIZER(), (_maxlen), 0 }