diff options
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 } |