Index: kern/uipc_mbuf.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.199 diff -u -p -r1.199 uipc_mbuf.c --- kern/uipc_mbuf.c 11 Dec 2014 19:21:57 -0000 1.199 +++ kern/uipc_mbuf.c 6 Feb 2015 13:22:33 -0000 @@ -1309,6 +1309,35 @@ ml_dechain(struct mbuf_list *ml) return (m0); } +struct mbuf * +ml_filter(struct mbuf_list *ml, + int (*filter)(void *, const struct mbuf *), void *ctx) +{ + struct mbuf_list matches = MBUF_LIST_INITIALIZER(); + struct mbuf *m, *n; + struct mbuf **mp; + + mp = &ml->ml_head; + + for (m = ml->ml_head; m != NULL; m = n) { + n = m->m_nextpkt; + if ((*filter)(ctx, m)) { + *mp = n; + ml_enqueue(&matches, m); + } else { + mp = &m->m_nextpkt; + ml->ml_tail = m; + } + } + + /* fixup ml */ + if (ml->ml_head == NULL) + ml->ml_tail = NULL; + ml->ml_len -= ml_len(&matches); + + return (matches.ml_head); /* ml_dechain */ +} + /* * mbuf queues */ @@ -1382,6 +1411,19 @@ mq_dechain(struct mbuf_queue *mq) mtx_enter(&mq->mq_mtx); m0 = ml_dechain(&mq->mq_list); + mtx_leave(&mq->mq_mtx); + + return (m0); +} + +struct mbuf * +mq_filter(struct mbuf_queue *mq, + int (*filter)(void *, const struct mbuf *), void *ctx) +{ + struct mbuf *m0; + + mtx_enter(&mq->mq_mtx); + m0 = ml_filter(&mq->mq_list, filter, ctx); mtx_leave(&mq->mq_mtx); return (m0); Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.316 diff -u -p -r1.316 if.c --- net/if.c 5 Feb 2015 10:28:50 -0000 1.316 +++ net/if.c 6 Feb 2015 13:22:33 -0000 @@ -127,7 +127,8 @@ void if_attachsetup(struct ifnet *); void if_attachdomain1(struct ifnet *); void if_attach_common(struct ifnet *); -void if_detach_queues(struct ifnet *, struct ifqueue *); +int if_detach_filter(void *, const struct mbuf *); +void if_detach_queues(struct ifnet *, struct mbuf_queue *); void if_detached_start(struct ifnet *); int if_detached_ioctl(struct ifnet *, u_long, caddr_t); @@ -139,7 +140,6 @@ int if_setgroupattribs(caddr_t); int if_clone_list(struct if_clonereq *); struct if_clone *if_clone_lookup(const char *, int *); -void if_congestion_clear(void *); int if_group_egress_build(void); void if_link_state_change_task(void *); @@ -515,7 +515,7 @@ if_detach(struct ifnet *ifp) */ #define IF_DETACH_QUEUES(x) \ do { \ - extern struct ifqueue x; \ + extern struct mbuf_queue x; \ if_detach_queues(ifp, & x); \ } while (0) IF_DETACH_QUEUES(arpintrq); @@ -567,38 +567,31 @@ do { \ splx(s); } -void -if_detach_queues(struct ifnet *ifp, struct ifqueue *q) +int +if_detach_filter(void *ctx, const struct mbuf *m) { - struct mbuf *m, *prev = NULL, *next; - int prio; + struct ifnet *ifp = ctx; - for (prio = 0; prio <= IFQ_MAXPRIO; prio++) { - for (m = q->ifq_q[prio].head; m; m = next) { - next = m->m_nextpkt; #ifdef DIAGNOSTIC - if ((m->m_flags & M_PKTHDR) == 0) { - prev = m; - continue; - } + if (!ISSET(m->m_flags, M_PKTHDR)) + return (0); #endif - if (m->m_pkthdr.rcvif != ifp) { - prev = m; - continue; - } - if (prev) - prev->m_nextpkt = m->m_nextpkt; - else - q->ifq_q[prio].head = m->m_nextpkt; - if (q->ifq_q[prio].tail == m) - q->ifq_q[prio].tail = prev; - q->ifq_len--; - - m->m_nextpkt = NULL; - m_freem(m); - IF_DROP(q); - } + return (m->m_pkthdr.rcvif == ifp); +} + +void +if_detach_queues(struct ifnet *ifp, struct mbuf_queue *mq) +{ + struct mbuf *m0, *m; + + m0 = mq_filter(mq, if_detach_filter, ifp); + while (m0 != NULL) { + m = m0; + m0 = m->m_nextpkt; + + m->m_nextpkt = NULL; + m_freem(m); } } @@ -760,36 +753,6 @@ if_clone_list(struct if_clonereq *ifcr) return (error); } -/* - * set queue congestion marker and register timeout to clear it - */ -void -if_congestion(struct ifqueue *ifq) -{ - /* Not currently needed, all callers check this */ - if (ifq->ifq_congestion) - return; - - ifq->ifq_congestion = malloc(sizeof(struct timeout), M_TEMP, M_NOWAIT); - if (ifq->ifq_congestion == NULL) - return; - timeout_set(ifq->ifq_congestion, if_congestion_clear, ifq); - timeout_add(ifq->ifq_congestion, hz / 100); -} - -/* - * clear the congestion flag - */ -void -if_congestion_clear(void *arg) -{ - struct ifqueue *ifq = arg; - struct timeout *to = ifq->ifq_congestion; - - ifq->ifq_congestion = NULL; - free(to, M_TEMP, sizeof(*to)); -} - #define equal(a1, a2) \ (bcmp((caddr_t)(a1), (caddr_t)(a2), \ ((struct sockaddr *)(a1))->sa_len) == 0) @@ -2097,7 +2060,7 @@ ifpromisc(struct ifnet *ifp, int pswitch int sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp, - void *newp, size_t newlen, struct ifqueue *ifq) + void *newp, size_t newlen, struct mbuf_queue *mq) { /* All sysctl names at this level are terminal. */ if (namelen != 1) @@ -2105,12 +2068,12 @@ sysctl_ifq(int *name, u_int namelen, voi switch (name[0]) { case IFQCTL_LEN: - return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len)); + return (sysctl_rdint(oldp, oldlenp, newp, mq_len(mq))); case IFQCTL_MAXLEN: return (sysctl_int(oldp, oldlenp, newp, newlen, - &ifq->ifq_maxlen)); + &mq->mq_maxlen)); /* XXX */ case IFQCTL_DROPS: - return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops)); + return (sysctl_rdint(oldp, oldlenp, newp, mq_drops(mq))); default: return (EOPNOTSUPP); } Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.185 diff -u -p -r1.185 if_ethersubr.c --- net/if_ethersubr.c 8 Jan 2015 14:29:18 -0000 1.185 +++ net/if_ethersubr.c 6 Feb 2015 13:22:33 -0000 @@ -443,12 +443,13 @@ bad: void ether_input(struct ifnet *ifp0, struct ether_header *eh, struct mbuf *m) { - struct ifqueue *inq; + struct mbuf_queue *inq; u_int16_t etype; - int s, llcfound = 0; + int llcfound = 0; struct llc *l; struct arpcom *ac; struct ifnet *ifp = ifp0; + int isr; #if NTRUNK > 0 int i = 0; #endif @@ -591,52 +592,46 @@ ether_input(struct ifnet *ifp0, struct e } } - /* - * Schedule softnet interrupt and enqueue packet within the same spl. - */ - s = splnet(); decapsulate: - switch (etype) { case ETHERTYPE_IP: - schednetisr(NETISR_IP); inq = &ipintrq; + isr = NETISR_IP; break; case ETHERTYPE_ARP: if (ifp->if_flags & IFF_NOARP) goto dropanyway; - schednetisr(NETISR_ARP); + inq = &arpintrq; + isr = NETISR_ARP; break; case ETHERTYPE_REVARP: if (ifp->if_flags & IFF_NOARP) goto dropanyway; revarpinput(m); /* XXX queue? */ - goto done; - + return; #ifdef INET6 /* * Schedule IPv6 software interrupt for incoming IPv6 packet. */ case ETHERTYPE_IPV6: - schednetisr(NETISR_IPV6); inq = &ip6intrq; + isr = NETISR_IPV6; break; + #endif /* INET6 */ #if NPPPOE > 0 || defined(PIPEX) case ETHERTYPE_PPPOEDISC: case ETHERTYPE_PPPOE: #ifndef PPPOE_SERVER - if (m->m_flags & (M_MCAST | M_BCAST)) { - m_freem(m); - goto done; - } + if (m->m_flags & (M_MCAST | M_BCAST)) + goto dropanyway; #endif M_PREPEND(m, sizeof(*eh), M_DONTWAIT); if (m == NULL) - goto done; + return; eh_tmp = mtod(m, struct ether_header *); /* @@ -651,7 +646,7 @@ decapsulate: if ((session = pipex_pppoe_lookup_session(m)) != NULL) { pipex_pppoe_input(m, session); - goto done; + return; } } #endif @@ -660,14 +655,14 @@ decapsulate: else inq = &pppoeinq; - schednetisr(NETISR_PPPOE); + isr = NETISR_PPPOE; break; #endif #ifdef MPLS case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MCAST: inq = &mplsintrq; - schednetisr(NETISR_MPLS); + isr = NETISR_MPLS; break; #endif default: @@ -686,21 +681,24 @@ decapsulate: m_adj(m, 6); M_PREPEND(m, sizeof(*eh), M_DONTWAIT); if (m == NULL) - goto done; + return; *mtod(m, struct ether_header *) = *eh; goto decapsulate; } - goto dropanyway; - dropanyway: + /* FALLTHROUGH */ default: - m_freem(m); - goto done; + goto dropanyway; + /* NOTREACHED */ } } - IF_INPUT_ENQUEUE(inq, m); -done: - splx(s); + if (mq_enqueue(inq, m) == 0) + schednetisr(isr); + + return; + +dropanyway: + m_freem(m); } /* Index: net/if_loop.c =================================================================== RCS file: /cvs/src/sys/net/if_loop.c,v retrieving revision 1.63 diff -u -p -r1.63 if_loop.c --- net/if_loop.c 27 Jan 2015 10:20:31 -0000 1.63 +++ net/if_loop.c 6 Feb 2015 13:22:33 -0000 @@ -204,8 +204,8 @@ int looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { - int s, isr; - struct ifqueue *ifq = 0; + int isr; + struct mbuf_queue *ifq; if ((m->m_flags & M_PKTHDR) == 0) panic("looutput: no header mbuf"); @@ -252,18 +252,14 @@ looutput(struct ifnet *ifp, struct mbuf m_freem(m); return (EAFNOSUPPORT); } - s = splnet(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - splx(s); + + if (mq_enqueue(ifq, m) != 0) return (ENOBUFS); - } - IF_ENQUEUE(ifq, m); + schednetisr(isr); ifp->if_ipackets++; ifp->if_ibytes += m->m_pkthdr.len; - splx(s); + return (0); } Index: net/if_mpe.c =================================================================== RCS file: /cvs/src/sys/net/if_mpe.c,v retrieving revision 1.41 diff -u -p -r1.41 if_mpe.c --- net/if_mpe.c 22 Dec 2014 11:05:53 -0000 1.41 +++ net/if_mpe.c 6 Feb 2015 13:22:33 -0000 @@ -355,7 +355,7 @@ mpe_input(struct mbuf *m, struct ifnet * u_int8_t ttl) { struct ip *ip; - int s, hlen; + int hlen; /* label -> AF lookup */ @@ -392,10 +392,8 @@ mpe_input(struct mbuf *m, struct ifnet * if (ifp && ifp->if_bpf) bpf_mtap_af(ifp->if_bpf, AF_INET, m, BPF_DIRECTION_IN); #endif - s = splnet(); - IF_INPUT_ENQUEUE(&ipintrq, m); - schednetisr(NETISR_IP); - splx(s); + if (mq_enqueue(&ipintrq, m) == 0) + schednetisr(NETISR_IP); } #ifdef INET6 @@ -404,7 +402,6 @@ mpe_input6(struct mbuf *m, struct ifnet u_int8_t ttl) { struct ip6_hdr *ip6hdr; - int s; /* label -> AF lookup */ @@ -427,10 +424,9 @@ mpe_input6(struct mbuf *m, struct ifnet if (ifp && ifp->if_bpf) bpf_mtap_af(ifp->if_bpf, AF_INET6, m, BPF_DIRECTION_IN); #endif - s = splnet(); - IF_INPUT_ENQUEUE(&ip6intrq, m); - schednetisr(NETISR_IPV6); - splx(s); + + if (mq_enqueue(&ip6intrq, m) == 0) + schednetisr(NETISR_IPV6); } #endif /* INET6 */ Index: net/if_ppp.c =================================================================== RCS file: /cvs/src/sys/net/if_ppp.c,v retrieving revision 1.80 diff -u -p -r1.80 if_ppp.c --- net/if_ppp.c 19 Dec 2014 17:14:39 -0000 1.80 +++ net/if_ppp.c 6 Feb 2015 13:22:33 -0000 @@ -232,7 +232,7 @@ ppp_clone_create(struct if_clone *ifc, i sc->sc_if.if_output = pppoutput; sc->sc_if.if_start = ppp_ifstart; IFQ_SET_MAXLEN(&sc->sc_if.if_snd, IFQ_MAXLEN); - IFQ_SET_MAXLEN(&sc->sc_inq, IFQ_MAXLEN); + mq_init(&sc->sc_inq, IFQ_MAXLEN, IPL_NET); IFQ_SET_MAXLEN(&sc->sc_fastq, IFQ_MAXLEN); IFQ_SET_MAXLEN(&sc->sc_rawq, IFQ_MAXLEN); IFQ_SET_READY(&sc->sc_if.if_snd); @@ -329,12 +329,8 @@ pppdealloc(struct ppp_softc *sc) break; m_freem(m); } - for (;;) { - IF_DEQUEUE(&sc->sc_inq, m); - if (m == NULL) - break; + while ((m = mq_dequeue(&sc->sc_inq)) != NULL) m_freem(m); - } for (;;) { IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) @@ -398,7 +394,7 @@ pppioctl(struct ppp_softc *sc, u_long cm switch (cmd) { case FIONREAD: - *(int *)data = IFQ_LEN(&sc->sc_inq); + *(int *)data = mq_len(&sc->sc_inq); break; case PPPIOCGUNIT: @@ -1225,7 +1221,7 @@ static void ppp_inproc(struct ppp_softc *sc, struct mbuf *m) { struct ifnet *ifp = &sc->sc_if; - struct ifqueue *inq; + struct mbuf_queue *inq; int s, ilen, xlen, proto, rv; u_char *cp, adrs, ctrl; struct mbuf *mp, *dmp = NULL; @@ -1459,10 +1455,10 @@ ppp_inproc(struct ppp_softc *sc, struct m_freem(m); return; } + m->m_pkthdr.len -= PPP_HDRLEN; m->m_data += PPP_HDRLEN; m->m_len -= PPP_HDRLEN; - schednetisr(NETISR_IP); inq = &ipintrq; break; @@ -1478,29 +1474,27 @@ ppp_inproc(struct ppp_softc *sc, struct /* * Put the packet on the appropriate input queue. */ - s = splnet(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - splx(s); + if (mq_enqueue(&sc->sc_inq, m) != 0) { if (sc->sc_flags & SC_DEBUG) printf("%s: input queue full\n", ifp->if_xname); ifp->if_iqdrops++; - if (!inq->ifq_congestion) - if_congestion(inq); - goto bad; + goto dropped; } - IF_ENQUEUE(inq, m); - splx(s); ifp->if_ipackets++; ifp->if_ibytes += ilen; if (rv) (*sc->sc_ctlp)(sc); +#ifdef INET + else + schednetisr(NETISR_IP); +#endif /* INET */ return; bad: m_freem(m); + dropped: sc->sc_if.if_ierrors++; sc->sc_stats.ppp_ierrors++; } Index: net/if_pppoe.c =================================================================== RCS file: /cvs/src/sys/net/if_pppoe.c,v retrieving revision 1.43 diff -u -p -r1.43 if_pppoe.c --- net/if_pppoe.c 5 Dec 2014 15:50:04 -0000 1.43 +++ net/if_pppoe.c 6 Feb 2015 13:22:33 -0000 @@ -147,8 +147,8 @@ struct pppoe_softc { }; /* incoming traffic will be queued here */ -struct ifqueue pppoediscinq; -struct ifqueue pppoeinq; +struct mbuf_queue pppoediscinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); +struct mbuf_queue pppoeinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);; /* input routines */ static void pppoe_disc_input(struct mbuf *); @@ -201,9 +201,6 @@ pppoeattach(int count) { LIST_INIT(&pppoe_softc_list); if_clone_attach(&pppoe_cloner); - - IFQ_SET_MAXLEN(&pppoediscinq, IFQ_MAXLEN); - IFQ_SET_MAXLEN(&pppoeinq, IFQ_MAXLEN); } /* Create a new interface. */ @@ -360,27 +357,14 @@ void pppoeintr(void) { struct mbuf *m; - int s; splsoftassert(IPL_SOFTNET); - - for (;;) { - s = splnet(); - IF_DEQUEUE(&pppoediscinq, m); - splx(s); - if (m == NULL) - break; + + while ((m = mq_dequeue(&pppoediscinq)) != NULL) pppoe_disc_input(m); - } - for (;;) { - s = splnet(); - IF_DEQUEUE(&pppoeinq, m); - splx(s); - if (m == NULL) - break; + while ((m = mq_dequeue(&pppoeinq)) != NULL) pppoe_data_input(m); - } } /* Analyze and handle a single received packet while not in session state. */ Index: net/if_pppoe.h =================================================================== RCS file: /cvs/src/sys/net/if_pppoe.h,v retrieving revision 1.5 diff -u -p -r1.5 if_pppoe.h --- net/if_pppoe.h 28 Aug 2008 13:10:54 -0000 1.5 +++ net/if_pppoe.h 6 Feb 2015 13:22:33 -0000 @@ -66,8 +66,8 @@ struct pppoeconnectionstate { #ifdef _KERNEL -extern struct ifqueue pppoediscinq; -extern struct ifqueue pppoeinq; +extern struct mbuf_queue pppoediscinq; +extern struct mbuf_queue pppoeinq; void pppoeintr(void); Index: net/if_pppvar.h =================================================================== RCS file: /cvs/src/sys/net/if_pppvar.h,v retrieving revision 1.15 diff -u -p -r1.15 if_pppvar.h --- net/if_pppvar.h 7 Dec 2003 15:41:27 -0000 1.15 +++ net/if_pppvar.h 6 Feb 2015 13:22:33 -0000 @@ -98,7 +98,7 @@ struct ppp_softc { u_int16_t sc_mru; /* max receive unit */ pid_t sc_xfer; /* used in transferring unit */ struct ifqueue sc_rawq; /* received packets */ - struct ifqueue sc_inq; /* queue of input packets for daemon */ + struct mbuf_queue sc_inq; /* queue of input packets for daemon */ struct ifqueue sc_fastq; /* interactive output packet q */ struct mbuf *sc_togo; /* output packet ready to go */ struct mbuf *sc_npqueue; /* output packets not to be sent yet */ Index: net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.35 diff -u -p -r1.35 if_pppx.c --- net/if_pppx.c 19 Dec 2014 17:14:39 -0000 1.35 +++ net/if_pppx.c 6 Feb 2015 13:22:33 -0000 @@ -122,7 +122,7 @@ struct pppx_dev { struct mutex pxd_wsel_mtx; /* queue of packets for userland to service - protected by splnet */ - struct ifqueue pxd_svcq; + struct mbuf_queue pxd_svcq; int pxd_waiting; LIST_HEAD(,pppx_if) pxd_pxis; }; @@ -258,7 +258,7 @@ pppxopen(dev_t dev, int flags, int mode, mtx_init(&pxd->pxd_wsel_mtx, IPL_NET); LIST_INIT(&pxd->pxd_pxis); - IFQ_SET_MAXLEN(&pxd->pxd_svcq, 128); + mq_init(&pxd->pxd_svcq, 128, IPL_NET); LIST_INSERT_HEAD(&pppx_devs, pxd, pxd_entry); out: @@ -277,25 +277,17 @@ pppxread(dev_t dev, struct uio *uio, int if (!pxd) return (ENXIO); - s = splnet(); - for (;;) { - IF_DEQUEUE(&pxd->pxd_svcq, m0); - if (m0 != NULL) - break; - - if (ISSET(ioflag, IO_NDELAY)) { - splx(s); + while ((m0 = mq_dequeue(&pxd->pxd_svcq)) == NULL) { + if (ISSET(ioflag, IO_NDELAY)) return (EWOULDBLOCK); - } + s = splnet(); pxd->pxd_waiting = 1; error = tsleep(pxd, (PZERO + 1)|PCATCH, "pppxread", 0); - if (error != 0) { - splx(s); + splx(s); + if (error != 0) return (error); - } } - splx(s); while (m0 != NULL && uio->uio_resid > 0 && error == 0) { len = min(uio->uio_resid, m0->m_len); @@ -317,9 +309,9 @@ pppxwrite(dev_t dev, struct uio *uio, in /* struct pppx_dev *pxd = pppx_dev2pxd(dev); */ struct pppx_hdr *th; struct mbuf *top, **mp, *m; - struct ifqueue *ifq; + struct mbuf_queue *ifq; int tlen, mlen; - int isr, s, error = 0; + int isr, error = 0; if (uio->uio_resid < sizeof(*th) || uio->uio_resid > MCLBYTES) return (EMSGSIZE); @@ -394,16 +386,10 @@ pppxwrite(dev_t dev, struct uio *uio, in return (EAFNOSUPPORT); } - s = splnet(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - splx(s); - m_freem(top); + if (mq_enqueue(ifq, top) != 0) return (ENOBUFS); - } - IF_ENQUEUE(ifq, top); + schednetisr(isr); - splx(s); return (error); } @@ -471,13 +457,11 @@ int pppxpoll(dev_t dev, int events, struct proc *p) { struct pppx_dev *pxd = pppx_dev2pxd(dev); - int s, revents = 0; + int revents = 0; if (events & (POLLIN | POLLRDNORM)) { - s = splnet(); - if (!IF_IS_EMPTY(&pxd->pxd_svcq)) + if (!mq_empty(&pxd->pxd_svcq)) revents |= events & (POLLIN | POLLRDNORM); - splx(s); } if (events & (POLLOUT | POLLWRNORM)) revents |= events & (POLLOUT | POLLWRNORM); @@ -539,21 +523,15 @@ int filt_pppx_read(struct knote *kn, long hint) { struct pppx_dev *pxd = (struct pppx_dev *)kn->kn_hook; - int s, event = 0; if (ISSET(kn->kn_status, KN_DETACHED)) { kn->kn_data = 0; return (1); } - s = splnet(); - if (!IF_IS_EMPTY(&pxd->pxd_svcq)) { - event = 1; - kn->kn_data = IF_LEN(&pxd->pxd_svcq); - } - splx(s); + kn->kn_data = mq_len(&pxd->pxd_svcq); - return (event); + return (kn->kn_data > 0); } void @@ -582,7 +560,8 @@ pppxclose(dev_t dev, int flags, int mode { struct pppx_dev *pxd; struct pppx_if *pxi; - int s; + struct mbuf_list ml; + struct mbuf *m; rw_enter_write(&pppx_devs_lk); @@ -594,10 +573,7 @@ pppxclose(dev_t dev, int flags, int mode LIST_REMOVE(pxd, pxd_entry); - s = splnet(); - IF_PURGE(&pxd->pxd_svcq); - splx(s); - + mq_delist(&pxd->pxd_svcq, &ml); free(pxd, M_DEVBUF, 0); if (LIST_EMPTY(&pppx_devs)) { @@ -607,6 +583,10 @@ pppxclose(dev_t dev, int flags, int mode } rw_exit_write(&pppx_devs_lk); + + while ((m = ml_dequeue(&ml)) != NULL) + m_freem(m); + return (0); } Index: net/if_spppsubr.c =================================================================== RCS file: /cvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.130 diff -u -p -r1.130 if_spppsubr.c --- net/if_spppsubr.c 27 Jan 2015 03:17:36 -0000 1.130 +++ net/if_spppsubr.c 6 Feb 2015 13:22:33 -0000 @@ -437,11 +437,11 @@ void sppp_input(struct ifnet *ifp, struct mbuf *m) { struct ppp_header ht; - struct ifqueue *inq = 0; + struct mbuf_queue *inq = NULL; + int isr; struct sppp *sp = (struct sppp *)ifp; struct timeval tv; int debug = ifp->if_flags & IFF_DEBUG; - int s; if (ifp->if_flags & IFF_UP) { /* Count received bytes, add hardware framing */ @@ -458,9 +458,10 @@ sppp_input(struct ifnet *ifp, struct mbu SPP_FMT "input packet is too small, %d bytes\n", SPP_ARGS(ifp), m->m_pkthdr.len); drop: + m_freem (m); + dropped: ++ifp->if_ierrors; ++ifp->if_iqdrops; - m_freem (m); return; } @@ -538,8 +539,8 @@ sppp_input(struct ifnet *ifp, struct mbu return; case PPP_IP: if (sp->state[IDX_IPCP] == STATE_OPENED) { - schednetisr (NETISR_IP); inq = &ipintrq; + isr = NETISR_IP; sp->pp_last_activity = tv.tv_sec; } break; @@ -551,8 +552,8 @@ sppp_input(struct ifnet *ifp, struct mbu return; case PPP_IPV6: if (sp->state[IDX_IPV6CP] == STATE_OPENED) { - schednetisr (NETISR_IPV6); inq = &ip6intrq; + isr = NETISR_IPV6; sp->pp_last_activity = tv.tv_sec; } break; @@ -580,13 +581,13 @@ sppp_input(struct ifnet *ifp, struct mbu m_freem (m); return; case ETHERTYPE_IP: - schednetisr (NETISR_IP); inq = &ipintrq; + isr = NETISR_IP; break; #ifdef INET6 case ETHERTYPE_IPV6: - schednetisr (NETISR_IPV6); inq = &ip6intrq; + isr = NETISR_IPV6; break; #endif } @@ -602,24 +603,13 @@ sppp_input(struct ifnet *ifp, struct mbu goto drop; } - if (! (ifp->if_flags & IFF_UP) || ! inq) + if (inq == NULL || !ISSET(ifp->if_flags, IFF_UP)) goto drop; - /* Check queue. */ - s = splnet(); - if (IF_QFULL (inq)) { - /* Queue overflow. */ - IF_DROP(inq); - splx(s); - if (debug) - log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", - SPP_ARGS(ifp)); - if (!inq->ifq_congestion) - if_congestion(inq); - goto drop; - } - IF_ENQUEUE(inq, m); - splx(s); + if (mq_enqueue(inq, m) != 0) + goto dropped; + + schednetisr(isr); } /* Index: net/if_tun.c =================================================================== RCS file: /cvs/src/sys/net/if_tun.c,v retrieving revision 1.131 diff -u -p -r1.131 if_tun.c --- net/if_tun.c 21 Jan 2015 02:23:14 -0000 1.131 +++ net/if_tun.c 6 Feb 2015 13:22:33 -0000 @@ -781,7 +781,7 @@ tunwrite(dev_t dev, struct uio *uio, int { struct tun_softc *tp; struct ifnet *ifp; - struct ifqueue *ifq; + struct mbuf_queue *ifq; u_int32_t *th; struct mbuf *top, **mp, *m; int isr; @@ -901,21 +901,15 @@ tunwrite(dev_t dev, struct uio *uio, int return (EAFNOSUPPORT); } - s = splnet(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - splx(s); + if (mq_enqueue(ifq, top) != 0) { ifp->if_collisions++; - m_freem(top); - if (!ifq->ifq_congestion) - if_congestion(ifq); return (ENOBUFS); } - IF_ENQUEUE(ifq, top); schednetisr(isr); + ifp->if_ipackets++; ifp->if_ibytes += top->m_pkthdr.len; - splx(s); + return (error); } Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.18 diff -u -p -r1.18 if_var.h --- net/if_var.h 6 Feb 2015 06:42:36 -0000 1.18 +++ net/if_var.h 6 Feb 2015 13:22:33 -0000 @@ -69,6 +69,7 @@ #include struct mbuf; +struct mbuf_queue; struct proc; struct rtentry; struct socket; @@ -409,9 +410,8 @@ void if_clone_detach(struct if_clone *); int if_clone_create(const char *); int if_clone_destroy(const char *); -void if_congestion(struct ifqueue *); int sysctl_ifq(int *, u_int, void *, size_t *, void *, size_t, - struct ifqueue *); + struct mbuf_queue *); int loioctl(struct ifnet *, u_long, caddr_t); void loopattach(int); Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.900 diff -u -p -r1.900 pf.c --- net/pf.c 5 Feb 2015 01:10:57 -0000 1.900 +++ net/pf.c 6 Feb 2015 13:22:33 -0000 @@ -222,7 +222,6 @@ int pf_compare_state_keys(struct pf_s struct pf_state *pf_find_state(struct pfi_kif *, struct pf_state_key_cmp *, u_int, struct mbuf *); int pf_src_connlimit(struct pf_state **); -int pf_check_congestion(struct ifqueue *); int pf_match_rcvif(struct mbuf *, struct pf_rule *); void pf_step_into_anchor(int *, struct pf_ruleset **, struct pf_rule **, struct pf_rule **); @@ -3072,7 +3071,6 @@ pf_test_rule(struct pf_pdesc *pd, struct struct tcphdr *th = pd->hdr.tcp; struct pf_state_key *skw = NULL, *sks = NULL; struct pf_rule_actions act; - struct ifqueue *ifq = &ipintrq; u_short reason; int rewrite = 0; int tag = -1; @@ -3087,16 +3085,6 @@ pf_test_rule(struct pf_pdesc *pd, struct act.rtableid = pd->rdomain; SLIST_INIT(&rules); -#ifdef INET6 - if (pd->af == AF_INET6) - ifq = &ip6intrq; -#endif - - if (pd->dir == PF_IN && pf_check_congestion(ifq)) { - REASON_SET(&reason, PFRES_CONGEST); - return (PF_DROP); - } - switch (pd->virtual_proto) { case IPPROTO_ICMP: icmptype = pd->hdr.icmp->icmp_type; @@ -6627,15 +6615,6 @@ done: } return (action); -} - -int -pf_check_congestion(struct ifqueue *ifq) -{ - if (ifq->ifq_congestion) - return (1); - else - return (0); } void Index: net/pipex.c =================================================================== RCS file: /cvs/src/sys/net/pipex.c,v retrieving revision 1.65 diff -u -p -r1.65 pipex.c --- net/pipex.c 19 Dec 2014 17:14:40 -0000 1.65 +++ net/pipex.c 6 Feb 2015 13:22:33 -0000 @@ -100,8 +100,8 @@ struct timeout pipex_timer_ch; /* call int pipex_prune = 1; /* walk list every seconds */ /* pipex traffic queue */ -struct ifqueue pipexinq; -struct ifqueue pipexoutq; +struct mbuf_queue pipexinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); +struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); struct pipex_tag { struct pipex_session *session; int proto; @@ -145,9 +145,6 @@ pipex_init(void) LIST_INIT(&pipex_id_hashtable[i]); for (i = 0; i < nitems(pipex_peer_addr_hashtable); i++) LIST_INIT(&pipex_peer_addr_hashtable[i]); - /* queue and softintr init */ - IFQ_SET_MAXLEN(&pipexinq, IFQ_MAXLEN); - IFQ_SET_MAXLEN(&pipexoutq, IFQ_MAXLEN); pipex_softintr = softintr_establish(IPL_SOFTNET, pipex_softintr_handler, NULL); } @@ -719,17 +716,11 @@ pipex_ppp_dequeue(void) struct mbuf *m; struct m_tag *mtag; struct pipex_tag *tag; - int c, s; + int c; /* ppp output */ for (c = 0; c < PIPEX_DEQUEUE_LIMIT; c++) { - s = splnet(); - IF_DEQUEUE(&pipexoutq, m); - if (m == NULL) { - splx(s); - break; - } - splx(s); + m = mq_dequeue(&pipexoutq); mtag = m_tag_find(m, PACKET_TAG_PIPEX, NULL); if (mtag == NULL) { @@ -763,13 +754,9 @@ pipex_ppp_dequeue(void) /* ppp input */ for (c = 0; c < PIPEX_DEQUEUE_LIMIT; c++) { - s = splnet(); - IF_DEQUEUE(&pipexinq, m); - if (m == NULL) { - splx(s); + m = mq_dequeue(&pipexinq); + if (m == NULL) break; - } - splx(s); mtag = m_tag_find(m, PACKET_TAG_PIPEX, NULL); if (mtag == NULL) { @@ -784,45 +771,33 @@ pipex_ppp_dequeue(void) * When packet remains in queue, it is necessary * to re-schedule software interrupt. */ - s = splnet(); - if (!IF_IS_EMPTY(&pipexinq) || !IF_IS_EMPTY(&pipexoutq)) + if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq)) softintr_schedule(pipex_softintr); - splx(s); } Static int pipex_ppp_enqueue(struct mbuf *m0, struct pipex_session *session, - struct ifqueue *queue) + struct mbuf_queue *queue) { struct pipex_tag *tag; struct m_tag *mtag; - int s; - s = splnet(); - if (IF_QFULL(queue)) { - IF_DROP(queue); - splx(s); - goto fail; - } mtag = m_tag_get(PACKET_TAG_PIPEX, sizeof(struct pipex_tag), M_NOWAIT); if (mtag == NULL) { - splx(s); - goto fail; + m_freem(m0); + return (1); } + m_tag_prepend(m0, mtag); tag = (struct pipex_tag *)(mtag + 1); tag->session = session; tag->proto = PPP_IP; /* XXX need to support other protocols */ - IF_ENQUEUE(queue, m0); - splx(s); + if (mq_enqueue(queue, m0) != 0) + return (1); softintr_schedule(pipex_softintr); return (0); - -fail: - /* caller is responsible for freeing m0 */ - return (1); } /*********************************************************************** @@ -884,7 +859,7 @@ pipex_timer(void *ignored_arg) * mbuf queued in pipexinq or pipexoutq may have a * refererce to this session. */ - if (!IF_IS_EMPTY(&pipexinq) || !IF_IS_EMPTY(&pipexoutq)) + if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq)) continue; pipex_destroy_session(session); @@ -981,14 +956,17 @@ pipex_ip_output(struct mbuf *m0, struct /* * Multicast packet is a idle packet and it's not TCP. */ - if (session->ip_forward == 0 && session->ip6_forward == 0) - goto drop; + if (session->ip_forward == 0 && session->ip6_forward == 0) { + m_freem(m0); + goto dropped; + } + /* reset idle timer */ if (session->timeout_sec != 0) { is_idle = 0; m0 = ip_is_idle_packet(m0, &is_idle); if (m0 == NULL) - goto drop; + goto dropped; if (is_idle == 0) /* update expire time */ session->stat.idle_time = 0; @@ -998,19 +976,18 @@ pipex_ip_output(struct mbuf *m0, struct if ((session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) != 0) { m0 = adjust_tcp_mss(m0, session->peer_mru); if (m0 == NULL) - goto drop; + goto dropped; } } else m0->m_flags &= ~(M_BCAST|M_MCAST); /* output ip packets to the session tunnel */ if (pipex_ppp_enqueue(m0, session, &pipexoutq)) - goto drop; + goto dropped; return; -drop: - if (m0 != NULL) - m_freem(m0); + +dropped: session->stat.oerrors++; } @@ -1161,7 +1138,7 @@ pipex_ip_input(struct mbuf *m0, struct p { struct ifnet *ifp; struct ip *ip; - int s, len; + int len; int is_idle; /* change recvif */ @@ -1223,16 +1200,10 @@ pipex_ip_input(struct mbuf *m0, struct p bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN); #endif - s = splnet(); - if (IF_QFULL(&ipintrq)) { - IF_DROP(&ipintrq); + if (mq_enqueue(&ipintrq, m0) != 0) { ifp->if_collisions++; - if (!ipintrq.ifq_congestion) - if_congestion(&ipintrq); - splx(s); - goto drop; + goto dropped; } - IF_ENQUEUE(&ipintrq, m0); schednetisr(NETISR_IP); ifp->if_ipackets++; @@ -1240,12 +1211,11 @@ pipex_ip_input(struct mbuf *m0, struct p session->stat.ipackets++; session->stat.ibytes += len; - splx(s); - return; drop: if (m0 != NULL) m_freem(m0); +dropped: session->stat.ierrors++; } @@ -1255,7 +1225,7 @@ pipex_ip6_input(struct mbuf *m0, struct { struct ifnet *ifp; struct ip6_hdr *ip6; - int s, len; + int len; /* change recvif */ m0->m_pkthdr.rcvif = session->pipex_iface->ifnet_this; @@ -1298,16 +1268,10 @@ pipex_ip6_input(struct mbuf *m0, struct bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN); #endif - s = splnet(); - if (IF_QFULL(&ip6intrq)) { - IF_DROP(&ip6intrq); + if (mq_enqueue(&ip6intrq, m0) != 0) { ifp->if_collisions++; - if (!ip6intrq.ifq_congestion) - if_congestion(&ip6intrq); - splx(s); - goto drop; + goto dropped; } - IF_ENQUEUE(&ip6intrq, m0); schednetisr(NETISR_IPV6); ifp->if_ipackets++; @@ -1315,12 +1279,8 @@ pipex_ip6_input(struct mbuf *m0, struct session->stat.ipackets++; session->stat.ibytes += len; - splx(s); - return; -drop: - if (m0 != NULL) - m_freem(m0); +dropped: session->stat.ierrors++; } #endif @@ -1376,10 +1336,14 @@ pipex_common_input(struct pipex_session } /* input ppp packets to kernel session */ - if (pipex_ppp_enqueue(m0, session, &pipexinq) == 0) - return (NULL); + if (pipex_ppp_enqueue(m0, session, &pipexinq) != 0) + goto dropped; + + return (NULL); + drop: m_freem(m0); +dropped: session->stat.ierrors++; return (NULL); Index: net/pipex_local.h =================================================================== RCS file: /cvs/src/sys/net/pipex_local.h,v retrieving revision 1.21 diff -u -p -r1.21 pipex_local.h --- net/pipex_local.h 1 Dec 2014 06:55:05 -0000 1.21 +++ net/pipex_local.h 6 Feb 2015 13:22:33 -0000 @@ -427,7 +427,7 @@ Static struct mbuf *ip_is_idle Static void pipex_session_log (struct pipex_session *, int, const char *, ...) __attribute__((__format__(__printf__,3,4))); Static uint32_t pipex_sockaddr_hash_key(struct sockaddr *); Static int pipex_sockaddr_compar_addr(struct sockaddr *, struct sockaddr *); -Static int pipex_ppp_enqueue (struct mbuf *, struct pipex_session *, struct ifqueue *); +Static int pipex_ppp_enqueue (struct mbuf *, struct pipex_session *, struct mbuf_queue *); Static void pipex_ppp_dequeue (void); Static void pipex_timer_start (void); Static void pipex_timer_stop (void); Index: net/ppp_tty.c =================================================================== RCS file: /cvs/src/sys/net/ppp_tty.c,v retrieving revision 1.30 diff -u -p -r1.30 ppp_tty.c --- net/ppp_tty.c 5 Dec 2014 15:50:04 -0000 1.30 +++ net/ppp_tty.c 6 Feb 2015 13:22:33 -0000 @@ -303,7 +303,7 @@ pppread(struct tty *tp, struct uio *uio, splx(s); return 0; } - if (!IF_IS_EMPTY(&sc->sc_inq)) + if (!mq_empty(&sc->sc_inq)) break; if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0 && (tp->t_state & TS_ISOPEN)) { @@ -325,7 +325,7 @@ pppread(struct tty *tp, struct uio *uio, getc(&tp->t_canq); /* Get the packet from the input queue */ - IF_DEQUEUE(&sc->sc_inq, m0); + m0 = mq_dequeue(&sc->sc_inq); splx(s); for (m = m0; m && uio->uio_resid; m = m->m_next) Index: netinet/if_ether.c =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.c,v retrieving revision 1.144 diff -u -p -r1.144 if_ether.c --- netinet/if_ether.c 5 Feb 2015 03:01:03 -0000 1.144 +++ netinet/if_ether.c 6 Feb 2015 13:22:33 -0000 @@ -89,7 +89,8 @@ void in_arpinput(struct mbuf *); LIST_HEAD(, llinfo_arp) llinfo_arp; struct pool arp_pool; /* pool for llinfo_arp structures */ -struct ifqueue arpintrq; +/* XXX hate magic numbers */ +struct mbuf_queue arpintrq = MBUF_QUEUE_INITIALIZER(50, IPL_NET); int arp_inuse, arp_allocated; int arp_maxtries = 5; int arpinit_done; @@ -151,7 +152,6 @@ arp_rtrequest(int req, struct rtentry *r arpinit_done = 1; pool_init(&arp_pool, sizeof(struct llinfo_arp), 0, 0, 0, "arp", NULL); - IFQ_SET_MAXLEN(&arpintrq, 50); /* XXX hate magic numbers */ /* * We generate expiration times from time.tv_sec * so avoid accidently creating permanent routes. @@ -490,14 +490,9 @@ arpintr(void) { struct mbuf *m; struct arphdr *ar; - int s, len; + int len; - for (;;) { - s = splnet(); - IF_DEQUEUE(&arpintrq, m); - splx(s); - if (m == NULL) - break; + while ((m = mq_dequeue(&arpintrq)) != NULL) { #ifdef DIAGNOSTIC if ((m->m_flags & M_PKTHDR) == 0) panic("arpintr"); Index: netinet/if_ether.h =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.h,v retrieving revision 1.54 diff -u -p -r1.54 if_ether.h --- netinet/if_ether.h 5 Dec 2014 15:50:04 -0000 1.54 +++ netinet/if_ether.h 6 Feb 2015 13:22:33 -0000 @@ -199,7 +199,7 @@ struct sockaddr_inarp { extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN]; extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN]; extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN]; -extern struct ifqueue arpintrq; +extern struct mbuf_queue arpintrq; void arpwhohas(struct arpcom *, struct in_addr *); void arpintr(void); Index: netinet/in.h =================================================================== RCS file: /cvs/src/sys/netinet/in.h,v retrieving revision 1.111 diff -u -p -r1.111 in.h --- netinet/in.h 5 Dec 2014 15:50:04 -0000 1.111 +++ netinet/in.h 6 Feb 2015 13:22:33 -0000 @@ -779,7 +779,7 @@ __END_DECLS #ifdef _KERNEL extern int inetctlerrmap[]; -extern struct ifqueue ipintrq; /* ip packet input queue */ +extern struct mbuf_queue ipintrq; /* ip packet input queue */ extern struct in_addr zeroin_addr; struct mbuf; Index: netinet/ip_divert.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_divert.c,v retrieving revision 1.32 diff -u -p -r1.32 ip_divert.c --- netinet/ip_divert.c 24 Jan 2015 00:29:06 -0000 1.32 +++ netinet/ip_divert.c 6 Feb 2015 13:22:33 -0000 @@ -82,11 +82,10 @@ int divert_output(struct inpcb *inp, struct mbuf *m, struct mbuf *nam, struct mbuf *control) { - struct ifqueue *inq; struct sockaddr_in *sin; struct socket *so; struct ifaddr *ifa; - int s, error = 0, min_hdrlen = 0, dir; + int error = 0, min_hdrlen = 0, dir; struct ip *ip; u_int16_t off; @@ -149,8 +148,6 @@ divert_output(struct inpcb *inp, struct } m->m_pkthdr.rcvif = ifa->ifa_ifp; - inq = &ipintrq; - /* * Recalculate IP and protocol checksums for the inbound packet * since the userspace application may have modified the packet @@ -160,10 +157,8 @@ divert_output(struct inpcb *inp, struct ip->ip_sum = in_cksum(m, off); in_proto_cksum_out(m, NULL); - s = splnet(); - IF_INPUT_ENQUEUE(inq, m); - schednetisr(NETISR_IP); - splx(s); + if (mq_enqueue(&ipintrq, m) == 0) + schednetisr(NETISR_IP); } else { error = ip_output(m, NULL, &inp->inp_route, IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL, 0); Index: netinet/ip_ether.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ether.c,v retrieving revision 1.70 diff -u -p -r1.70 ip_ether.c --- netinet/ip_ether.c 19 Dec 2014 17:14:40 -0000 1.70 +++ netinet/ip_ether.c 6 Feb 2015 13:22:33 -0000 @@ -280,8 +280,6 @@ void mplsip_decap(struct mbuf *m, int iphlen) { struct gif_softc *sc; - struct ifqueue *ifq; - int s; etheripstat.etherip_ipackets++; @@ -330,22 +328,14 @@ mplsip_decap(struct mbuf *m, int iphlen) pf_pkt_addr_changed(m); #endif - ifq = &mplsintrq; - s = splnet(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if (mq_enqueue(&mplsintrq, m) != 0) { etheripstat.etherip_qfull++; - splx(s); DPRINTF(("mplsip_input(): packet dropped because of full " "queue\n")); return; } - IF_ENQUEUE(ifq, m); schednetisr(NETISR_MPLS); - splx(s); - return; } #endif Index: netinet/ip_gre.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_gre.c,v retrieving revision 1.52 diff -u -p -r1.52 ip_gre.c --- netinet/ip_gre.c 19 Dec 2014 17:14:40 -0000 1.52 +++ netinet/ip_gre.c 6 Feb 2015 13:22:33 -0000 @@ -93,8 +93,8 @@ int gre_input2(struct mbuf *m, int hlen, u_char proto) { struct greip *gip; - int s; - struct ifqueue *ifq; + struct mbuf_queue *ifq; + int isr; struct gre_softc *sc; u_short flags; u_int af; @@ -153,14 +153,15 @@ gre_input2(struct mbuf *m, int hlen, u_c */ if (!gre_wccp) return (0); - case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */ - ifq = &ipintrq; /* we are in ip_input */ + case ETHERTYPE_IP: + ifq = &ipintrq; + isr = NETISR_IP; af = AF_INET; break; #ifdef INET6 case ETHERTYPE_IPV6: ifq = &ip6intrq; - schednetisr(NETISR_IPV6); + isr = NETISR_IPV6; af = AF_INET6; break; #endif @@ -173,7 +174,7 @@ gre_input2(struct mbuf *m, int hlen, u_c case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MCAST: ifq = &mplsintrq; - schednetisr(NETISR_MPLS); + isr = NETISR_MPLS; af = AF_MPLS; break; #endif @@ -201,9 +202,8 @@ gre_input2(struct mbuf *m, int hlen, u_c pf_pkt_addr_changed(m); #endif - s = splnet(); /* possible */ - IF_INPUT_ENQUEUE(ifq, m); - splx(s); + if (mq_enqueue(ifq, m) == 0) + schednetisr(isr); return (1); /* packet is done, no further processing needed */ } @@ -263,9 +263,8 @@ gre_mobile_input(struct mbuf *m, ...) { struct ip *ip; struct mobip_h *mip; - struct ifqueue *ifq; struct gre_softc *sc; - int hlen, s; + int hlen; va_list ap; u_char osrc = 0; int msiz; @@ -331,16 +330,13 @@ gre_mobile_input(struct mbuf *m, ...) ip->ip_sum = 0; ip->ip_sum = in_cksum(m,(ip->ip_hl << 2)); - ifq = &ipintrq; - #if NBPFILTER > 0 if (sc->sc_if.if_bpf) bpf_mtap_af(sc->sc_if.if_bpf, AF_INET, m, BPF_DIRECTION_IN); #endif - s = splnet(); /* possible */ - IF_INPUT_ENQUEUE(ifq, m); - splx(s); + if (mq_enqueue(&ipintrq, m) == 0) + schednetisr(NETISR_IP); } /* Index: netinet/ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.244 diff -u -p -r1.244 ip_input.c --- netinet/ip_input.c 12 Jan 2015 13:51:45 -0000 1.244 +++ netinet/ip_input.c 6 Feb 2015 13:22:33 -0000 @@ -114,7 +114,7 @@ int ip_frags = 0; int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS; -struct ifqueue ipintrq; +struct mbuf_queue ipintrq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); struct pool ipqent_pool; struct pool ipq_pool; @@ -170,7 +170,6 @@ ip_init(void) pr->pr_protocol < IPPROTO_MAX) ip_protox[pr->pr_protocol] = pr - inetsw; LIST_INIT(&ipq); - IFQ_SET_MAXLEN(&ipintrq, IFQ_MAXLEN); if (ip_mtudisc != 0) ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); @@ -193,18 +192,8 @@ void ipintr(void) { struct mbuf *m; - int s; - for (;;) { - /* - * Get next datagram off input queue and get IP header - * in first mbuf. - */ - s = splnet(); - IF_DEQUEUE(&ipintrq, m); - splx(s); - if (m == NULL) - return; + while ((m = mq_dequeue(&ipintrq)) != NULL) { #ifdef DIAGNOSTIC if ((m->m_flags & M_PKTHDR) == 0) panic("ipintr no HDR"); Index: netinet/ip_ipip.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ipip.c,v retrieving revision 1.56 diff -u -p -r1.56 ip_ipip.c --- netinet/ip_ipip.c 19 Dec 2014 17:14:40 -0000 1.56 +++ netinet/ip_ipip.c 6 Feb 2015 13:22:33 -0000 @@ -146,7 +146,7 @@ ipip_input(struct mbuf *m, int iphlen, s struct sockaddr_in *sin; struct ifnet *ifp; struct ifaddr *ifa; - struct ifqueue *ifq = NULL; + struct mbuf_queue *ifq = NULL; struct ip *ipo; u_int rdomain; #ifdef INET6 @@ -154,7 +154,7 @@ ipip_input(struct mbuf *m, int iphlen, s struct ip6_hdr *ip6; #endif int isr; - int mode, hlen, s; + int mode, hlen; u_int8_t itos, otos; u_int8_t v; sa_family_t af; @@ -374,23 +374,14 @@ ipip_input(struct mbuf *m, int iphlen, s pf_pkt_addr_changed(m); #endif - s = splnet(); /* isn't it already? */ - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if (mq_enqueue(ifq, m) != 0) { ipipstat.ipips_qfull++; - splx(s); - DPRINTF(("ipip_input(): packet dropped because of full " "queue\n")); return; } - - IF_ENQUEUE(ifq, m); schednetisr(isr); - splx(s); - return; } int Index: netinet/ipsec_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ipsec_input.c,v retrieving revision 1.126 diff -u -p -r1.126 ipsec_input.c --- netinet/ipsec_input.c 24 Jan 2015 00:29:06 -0000 1.126 +++ netinet/ipsec_input.c 6 Feb 2015 13:22:33 -0000 @@ -830,28 +830,20 @@ ah4_input(struct mbuf *m, ...) int ah4_input_cb(struct mbuf *m, ...) { - struct ifqueue *ifq = &ipintrq; - int s = splnet(); - /* * Interface pointer is already in first mbuf; chop off the * `outer' header and reschedule. */ - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if (mq_enqueue(&ipintrq, m) != 0) { ahstat.ahs_qfull++; - splx(s); - m_freem(m); DPRINTF(("ah4_input_cb(): dropped packet because of full " "IP queue\n")); return ENOBUFS; } - IF_ENQUEUE(ifq, m); schednetisr(NETISR_IP); - splx(s); return 0; } @@ -886,27 +878,19 @@ esp4_input(struct mbuf *m, ...) int esp4_input_cb(struct mbuf *m, ...) { - struct ifqueue *ifq = &ipintrq; - int s = splnet(); - /* * Interface pointer is already in first mbuf; chop off the * `outer' header and reschedule. */ - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if (mq_enqueue(&ipintrq, m) != 0) { espstat.esps_qfull++; - splx(s); - m_freem(m); DPRINTF(("esp4_input_cb(): dropped packet because of full " "IP queue\n")); return ENOBUFS; } - IF_ENQUEUE(ifq, m); schednetisr(NETISR_IP); - splx(s); return 0; } @@ -928,27 +912,18 @@ ipcomp4_input(struct mbuf *m, ...) int ipcomp4_input_cb(struct mbuf *m, ...) { - struct ifqueue *ifq = &ipintrq; - int s = splnet(); - /* * Interface pointer is already in first mbuf; chop off the * `outer' header and reschedule. */ - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if (mq_enqueue(&ipintrq, m) != 0) { ipcompstat.ipcomps_qfull++; - splx(s); - m_freem(m); DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n")); return ENOBUFS; } - IF_ENQUEUE(ifq, m); schednetisr(NETISR_IP); - splx(s); - return 0; } Index: netinet6/in6.h =================================================================== RCS file: /cvs/src/sys/netinet6/in6.h,v retrieving revision 1.78 diff -u -p -r1.78 in6.h --- netinet6/in6.h 10 Jan 2015 11:43:37 -0000 1.78 +++ netinet6/in6.h 6 Feb 2015 13:22:33 -0000 @@ -418,7 +418,7 @@ typedef __socklen_t socklen_t; /* length #ifdef _KERNEL extern u_char inet6ctlerrmap[]; -extern struct ifqueue ip6intrq; /* IP6 packet input queue */ +extern struct mbuf_queue ip6intrq; /* IP6 packet input queue */ extern struct in6_addr zeroin6_addr; struct mbuf; Index: netinet6/ip6_divert.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v retrieving revision 1.32 diff -u -p -r1.32 ip6_divert.c --- netinet6/ip6_divert.c 24 Jan 2015 00:29:06 -0000 1.32 +++ netinet6/ip6_divert.c 6 Feb 2015 13:22:33 -0000 @@ -86,11 +86,10 @@ int divert6_output(struct inpcb *inp, struct mbuf *m, struct mbuf *nam, struct mbuf *control) { - struct ifqueue *inq; struct sockaddr_in6 *sin6; struct socket *so; struct ifaddr *ifa; - int s, error = 0, min_hdrlen = 0, nxt = 0, off, dir; + int error = 0, min_hdrlen = 0, nxt = 0, off, dir; struct ip6_hdr *ip6; m->m_pkthdr.rcvif = NULL; @@ -159,19 +158,14 @@ divert6_output(struct inpcb *inp, struct } m->m_pkthdr.rcvif = ifa->ifa_ifp; - inq = &ip6intrq; - /* * Recalculate the protocol checksum for the inbound packet * since the userspace application may have modified the packet * prior to reinjection. */ in6_proto_cksum_out(m, NULL); - - s = splnet(); - IF_INPUT_ENQUEUE(inq, m); - schednetisr(NETISR_IPV6); - splx(s); + if (mq_enqueue(&ip6intrq, m) == 0) + schednetisr(NETISR_IPV6); } else { error = ip6_output(m, NULL, &inp->inp_route6, IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL, NULL); Index: netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.136 diff -u -p -r1.136 ip6_input.c --- netinet6/ip6_input.c 5 Feb 2015 01:10:57 -0000 1.136 +++ netinet6/ip6_input.c 6 Feb 2015 13:22:33 -0000 @@ -114,7 +114,7 @@ #endif struct in6_ifaddrhead in6_ifaddr; -struct ifqueue ip6intrq; +struct mbuf_queue ip6intrq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); struct ip6stat ip6stat; @@ -145,7 +145,6 @@ ip6_init(void) pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW && pr->pr_protocol < IPPROTO_MAX) ip6_protox[pr->pr_protocol] = pr - inet6sw; - IFQ_SET_MAXLEN(&ip6intrq, IFQ_MAXLEN); TAILQ_INIT(&in6_ifaddr); ip6_randomid_init(); nd6_init(); @@ -169,17 +168,10 @@ ip6_init2(void *dummy) void ip6intr(void) { - int s; struct mbuf *m; - for (;;) { - s = splnet(); - IF_DEQUEUE(&ip6intrq, m); - splx(s); - if (m == NULL) - return; + while ((m = mq_dequeue(&ip6intrq)) != NULL) ip6_input(m); - } } extern struct route_in6 ip6_forward_rt; Index: netmpls/mpls.h =================================================================== RCS file: /cvs/src/sys/netmpls/mpls.h,v retrieving revision 1.29 diff -u -p -r1.29 mpls.h --- netmpls/mpls.h 15 Jan 2015 23:50:31 -0000 1.29 +++ netmpls/mpls.h 6 Feb 2015 13:22:33 -0000 @@ -159,7 +159,7 @@ void mpe_input6(struct mbuf *, struct if extern int mpls_raw_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); -extern struct ifqueue mplsintrq; /* MPLS input queue */ +extern struct mbuf_queue mplsintrq; /* MPLS input queue */ extern int mpls_defttl; extern int mpls_mapttl_ip; extern int mpls_mapttl_ip6; Index: netmpls/mpls_input.c =================================================================== RCS file: /cvs/src/sys/netmpls/mpls_input.c,v retrieving revision 1.42 diff -u -p -r1.42 mpls_input.c --- netmpls/mpls_input.c 23 Dec 2014 03:24:08 -0000 1.42 +++ netmpls/mpls_input.c 6 Feb 2015 13:22:33 -0000 @@ -40,7 +40,7 @@ #include -struct ifqueue mplsintrq; +struct mbuf_queue mplsintrq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); #ifdef MPLS_DEBUG #define MPLS_LABEL_GET(l) ((ntohl((l) & MPLS_LABEL_MASK)) >> MPLS_LABEL_OFFSET) @@ -57,22 +57,14 @@ struct mbuf *mpls_do_error(struct mbuf * void mpls_init(void) { - IFQ_SET_MAXLEN(&mplsintrq, IFQ_MAXLEN); } void mplsintr(void) { struct mbuf *m; - int s; - for (;;) { - /* Get next datagram of input queue */ - s = splnet(); - IF_DEQUEUE(&mplsintrq, m); - splx(s); - if (m == NULL) - return; + while ((m = mq_dequeue(&mplsintrq)) != NULL) { #ifdef DIAGNOSTIC if ((m->m_flags & M_PKTHDR) == 0) panic("mplsintr no HDR"); @@ -91,7 +83,7 @@ mpls_input(struct mbuf *m) struct rtentry *rt = NULL; struct rt_mpls *rt_mpls; u_int8_t ttl; - int i, s, hasbos; + int i, hasbos; if (!ISSET(ifp->if_xflags, IFXF_MPLS)) { m_freem(m); @@ -158,10 +150,8 @@ mpls_input(struct mbuf *m) do_v4: if (mpls_ip_adjttl(m, ttl)) goto done; - s = splnet(); - IF_INPUT_ENQUEUE(&ipintrq, m); - schednetisr(NETISR_IP); - splx(s); + if (mq_enqueue(&ipintrq, m) == 0) + schednetisr(NETISR_IP); goto done; } continue; @@ -171,10 +161,8 @@ do_v4: do_v6: if (mpls_ip6_adjttl(m, ttl)) goto done; - s = splnet(); - IF_INPUT_ENQUEUE(&ip6intrq, m); - schednetisr(NETISR_IPV6); - splx(s); + if (mq_enqueue(&ip6intrq, m) == 0) + schednetisr(NETISR_IPV6); goto done; } continue; @@ -241,19 +229,15 @@ do_v6: case AF_INET: if (mpls_ip_adjttl(m, ttl)) break; - s = splnet(); - IF_INPUT_ENQUEUE(&ipintrq, m); - schednetisr(NETISR_IP); - splx(s); + if (mq_enqueue(&ipintrq, m) == 0) + schednetisr(NETISR_IP); break; #ifdef INET6 case AF_INET6: if (mpls_ip6_adjttl(m, ttl)) break; - s = splnet(); - IF_INPUT_ENQUEUE(&ip6intrq, m); - schednetisr(NETISR_IPV6); - splx(s); + if (mq_enqueue(&ip6intrq, m) == 0) + schednetisr(NETISR_IPV6); break; #endif default: Index: sys/mbuf.h =================================================================== RCS file: /cvs/src/sys/sys/mbuf.h,v retrieving revision 1.184 diff -u -p -r1.184 mbuf.h --- sys/mbuf.h 20 Jan 2015 18:12:49 -0000 1.184 +++ sys/mbuf.h 6 Feb 2015 13:22:33 -0000 @@ -500,6 +500,8 @@ void ml_init(struct mbuf_list *); void ml_enqueue(struct mbuf_list *, struct mbuf *); struct mbuf * ml_dequeue(struct mbuf_list *); struct mbuf * ml_dechain(struct mbuf_list *); +struct mbuf * ml_filter(struct mbuf_list *, + int (*)(void *, const struct mbuf *), void *); #define ml_len(_ml) ((_ml)->ml_len) #define ml_empty(_ml) ((_ml)->ml_len == 0) @@ -527,6 +529,8 @@ struct mbuf * mq_dequeue(struct mbuf_qu int mq_enlist(struct mbuf_queue *, struct mbuf_list *); void mq_delist(struct mbuf_queue *, struct mbuf_list *); struct mbuf * mq_dechain(struct mbuf_queue *); +struct mbuf * mq_filter(struct mbuf_queue *, + int (*)(void *, const struct mbuf *), void *); #define mq_len(_mq) ml_len(&(_mq)->mq_list) #define mq_empty(_mq) ml_empty(&(_mq)->mq_list)