From 954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85 Mon Sep 17 00:00:00 2001 From: jlemon Date: Sat, 25 Nov 2000 07:35:38 +0000 Subject: Lock down the network interface queues. The queue mutex must be obtained before adding/removing packets from the queue. Also, the if_obytes and if_omcasts fields should only be manipulated under protection of the mutex. IF_ENQUEUE, IF_PREPEND, and IF_DEQUEUE perform all necessary locking on the queue. An IF_LOCK macro is provided, as well as the old (mutex-less) versions of the macros in the form _IF_ENQUEUE, _IF_QFULL, for code which needs them, but their use is discouraged. Two new macros are introduced: IF_DRAIN() to drain a queue, and IF_HANDOFF, which takes care of locking/enqueue, and also statistics updating/start if necessary. --- sys/contrib/ipfilter/netinet/ip_auth.c | 12 +-- sys/dev/ar/if_ar.c | 11 ++- sys/dev/ar/if_ar_isa.c | 11 ++- sys/dev/awi/awi.c | 19 ++--- sys/dev/de/if_de.c | 16 ++-- sys/dev/en/midway.c | 26 +++--- sys/dev/hea/eni_receive.c | 16 ++-- sys/dev/hea/eni_transmit.c | 10 +-- sys/dev/hfa/fore_receive.c | 4 +- sys/dev/iicbus/if_ic.c | 9 +- sys/dev/lmc/if_lmc.c | 23 +++-- sys/dev/lmc/if_lmc_common.c | 4 +- sys/dev/pdq/pdq_ifsubr.c | 8 +- sys/dev/ppbus/if_plip.c | 24 +++--- sys/dev/sr/if_sr.c | 11 ++- sys/dev/sr/if_sr_isa.c | 11 ++- sys/dev/usb/udbp.c | 23 +++-- sys/dev/usb/usb_ethersubr.c | 14 +--- sys/i386/isa/if_ar.c | 11 ++- sys/i386/isa/if_sr.c | 11 ++- sys/i4b/driver/i4b_bsdi_ibc.c | 23 +++-- sys/i4b/driver/i4b_ing.c | 36 ++++---- sys/i4b/driver/i4b_ipr.c | 50 +++-------- sys/i4b/driver/i4b_isppp.c | 7 +- sys/i4b/driver/i4b_ispppsubr.c | 63 ++++---------- sys/i4b/driver/i4b_rbch.c | 43 +++------- sys/i4b/driver/i4b_tel.c | 32 +++---- sys/i4b/driver/i4b_trace.c | 17 ++-- sys/i4b/layer1/ifpi/i4b_ifpi_pci.c | 19 ++--- sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c | 19 ++--- sys/i4b/layer1/ihfc/i4b_ihfc_drv.c | 9 +- sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c | 4 +- sys/i4b/layer1/isic/i4b_bchan.c | 10 ++- sys/i4b/layer1/isic/i4b_hscx.c | 9 +- sys/i4b/layer1/iwic/i4b_iwic_bchan.c | 19 ++--- sys/i4b/layer2/i4b_l2.c | 3 +- sys/i4b/layer2/i4b_mbuf.c | 16 +--- sys/i4b/layer2/i4b_util.c | 2 +- sys/i4b/layer4/i4b_i4bdrv.c | 27 ++++-- sys/net/bridge.c | 16 +--- sys/net/if.c | 11 ++- sys/net/if_atmsubr.c | 21 +---- sys/net/if_ef.c | 18 +--- sys/net/if_ethersubr.c | 38 ++------- sys/net/if_fddisubr.c | 28 +------ sys/net/if_gif.c | 16 +--- sys/net/if_iso88025subr.c | 31 ++----- sys/net/if_loop.c | 26 ++---- sys/net/if_ppp.c | 99 +++++++++++----------- sys/net/if_sl.c | 18 ++-- sys/net/if_spppsubr.c | 69 ++++----------- sys/net/if_stf.c | 14 +--- sys/net/if_tun.c | 31 ++----- sys/net/if_var.h | 149 ++++++++++++++++++++++----------- sys/net/if_vlan.c | 14 +--- sys/net/intrq.c | 11 +-- sys/netatalk/ddp_pcb.c | 2 + sys/netatalk/ddp_usrreq.c | 2 + sys/netatm/atm_device.c | 2 + sys/netatm/atm_subr.c | 1 + sys/netatm/ipatm/ipatm_input.c | 11 +-- sys/netinet/if_ether.c | 13 ++- sys/netinet/ip_auth.c | 12 +-- sys/netinet/ip_input.c | 6 +- sys/netinet/ip_mroute.c | 12 +-- sys/netinet6/ah_input.c | 15 +--- sys/netinet6/esp_input.c | 15 +--- sys/netinet6/ip6_input.c | 1 + sys/netipx/ipx_input.c | 1 + sys/netipx/ipx_ip.c | 12 +-- sys/netnatm/natm_proto.c | 2 + sys/netns/ns_input.c | 1 + sys/netns/ns_ip.c | 13 +-- sys/pc98/cbus/olpt.c | 22 ++--- sys/pc98/pc98/olpt.c | 22 ++--- sys/pci/if_de.c | 16 ++-- sys/pci/if_wxvar.h | 4 + 77 files changed, 587 insertions(+), 890 deletions(-) (limited to 'sys') diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c index 4ce6a69..7fb9d21 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ b/sys/contrib/ipfilter/netinet/ip_auth.c @@ -286,9 +286,6 @@ int cmd; frentry_t *fr, **frptr; { mb_t *m; -#if defined(_KERNEL) && !SOLARIS - struct ifqueue *ifq; -#endif frauth_t auth, *au = &auth; frauthent_t *fae, **faep; int i, error = 0; @@ -423,15 +420,10 @@ fr_authioctlloop: # if SOLARIS error = fr_qin(fr_auth[i].fra_q, m); # else /* SOLARIS */ - ifq = &ipintrq; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if (! IF_HANDOFF(&ipintrq, m, NULL)) error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m); + else schednetisr(NETISR_IP); - } # endif /* SOLARIS */ if (error) fr_authstats.fas_quefail++; diff --git a/sys/dev/ar/if_ar.c b/sys/dev/ar/if_ar.c index f43aef1..dfbc3ac 100644 --- a/sys/dev/ar/if_ar.c +++ b/sys/dev/ar/if_ar.c @@ -515,6 +515,8 @@ arattach(struct ar_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "ar_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "ar_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -2308,13 +2310,16 @@ ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); arstart(sc); splx(s); return (0); diff --git a/sys/dev/ar/if_ar_isa.c b/sys/dev/ar/if_ar_isa.c index f43aef1..dfbc3ac 100644 --- a/sys/dev/ar/if_ar_isa.c +++ b/sys/dev/ar/if_ar_isa.c @@ -515,6 +515,8 @@ arattach(struct ar_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "ar_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "ar_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -2308,13 +2310,16 @@ ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); arstart(sc); splx(s); return (0); diff --git a/sys/dev/awi/awi.c b/sys/dev/awi/awi.c index 023796b..749e042 100644 --- a/sys/dev/awi/awi.c +++ b/sys/dev/awi/awi.c @@ -876,17 +876,12 @@ awi_stop(sc) ifp->if_timer = 0; sc->sc_tx_timer = sc->sc_rx_timer = sc->sc_mgt_timer = 0; for (;;) { - IF_DEQUEUE(&sc->sc_mgtq, m); - if (m == NULL) - break; - m_freem(m); - } - for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); + _IF_DEQUEUE(&sc->sc_mgtq, m); if (m == NULL) break; m_freem(m); } + IF_DRAIN(&ifp->if_snd); while ((bp = TAILQ_FIRST(&sc->sc_scan)) != NULL) { TAILQ_REMOVE(&sc->sc_scan, bp, list); free(bp, M_DEVBUF); @@ -955,10 +950,10 @@ awi_start(ifp) for (;;) { txd = sc->sc_txnext; - IF_DEQUEUE(&sc->sc_mgtq, m0); + _IF_DEQUEUE(&sc->sc_mgtq, m0); if (m0 != NULL) { if (awi_next_txd(sc, m0->m_pkthdr.len, &frame, &ntxd)) { - IF_PREPEND(&sc->sc_mgtq, m0); + _IF_PREPEND(&sc->sc_mgtq, m0); ifp->if_flags |= IFF_OACTIVE; break; } @@ -2096,7 +2091,7 @@ awi_send_deauth(sc) deauth += 2; m->m_pkthdr.len = m->m_len = deauth - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); + _IF_ENQUEUE(&sc->sc_mgtq, m); awi_start(ifp); awi_drvstate(sc, AWI_DRV_INFTOSS); } @@ -2141,7 +2136,7 @@ awi_send_auth(sc, seq) auth += 2; m->m_pkthdr.len = m->m_len = auth - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); + _IF_ENQUEUE(&sc->sc_mgtq, m); awi_start(ifp); sc->sc_mgt_timer = AWI_TRANS_TIMEOUT / 1000; @@ -2261,7 +2256,7 @@ awi_send_asreq(sc, reassoc) asreq += 2 + asreq[1]; m->m_pkthdr.len = m->m_len = asreq - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); + _IF_ENQUEUE(&sc->sc_mgtq, m); awi_start(ifp); sc->sc_mgt_timer = AWI_TRANS_TIMEOUT / 1000; diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c index aa624cd..108518e 100644 --- a/sys/dev/de/if_de.c +++ b/sys/dev/de/if_de.c @@ -3201,7 +3201,7 @@ tulip_reset( bus_dmamap_t map; #endif struct mbuf *m; - IF_DEQUEUE(&sc->tulip_txq, m); + _IF_DEQUEUE(&sc->tulip_txq, m); if (m == NULL) break; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) @@ -3247,7 +3247,7 @@ tulip_reset( bus_dmamap_t map; #endif struct mbuf *m; - IF_DEQUEUE(&sc->tulip_rxq, m); + _IF_DEQUEUE(&sc->tulip_rxq, m); if (m == NULL) break; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX) @@ -3382,7 +3382,7 @@ tulip_rx_intr( */ TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop)); if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) { - IF_DEQUEUE(&sc->tulip_rxq, ms); + _IF_DEQUEUE(&sc->tulip_rxq, ms); me = ms; } else { /* @@ -3422,7 +3422,7 @@ tulip_rx_intr( * won't go into the loop and thereby saving a ourselves from * doing a multiplication by 0 in the normal case). */ - IF_DEQUEUE(&sc->tulip_rxq, ms); + _IF_DEQUEUE(&sc->tulip_rxq, ms); for (me = ms; total_len > 0; total_len--) { #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX) map = M_GETCTX(me, bus_dmamap_t); @@ -3435,7 +3435,7 @@ tulip_rx_intr( #endif /* TULIP_BUS_DMA */ me->m_len = TULIP_RX_BUFLEN; last_offset += TULIP_RX_BUFLEN; - IF_DEQUEUE(&sc->tulip_rxq, me->m_next); + _IF_DEQUEUE(&sc->tulip_rxq, me->m_next); me = me->m_next; } } @@ -3644,7 +3644,7 @@ tulip_rx_intr( ri->ri_nextout = ri->ri_first; me = ms->m_next; ms->m_next = NULL; - IF_ENQUEUE(&sc->tulip_rxq, ms); + _IF_ENQUEUE(&sc->tulip_rxq, ms); } while ((ms = me) != NULL); if (sc->tulip_rxq.ifq_len >= TULIP_RXQ_TARGET) @@ -3702,7 +3702,7 @@ tulip_tx_intr( } } else { const u_int32_t d_status = ri->ri_nextin->d_status; - IF_DEQUEUE(&sc->tulip_txq, m); + _IF_DEQUEUE(&sc->tulip_txq, m); if (m != NULL) { #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t); @@ -4343,7 +4343,7 @@ tulip_txput( * The descriptors have been filled in. Now get ready * to transmit. */ - IF_ENQUEUE(&sc->tulip_txq, m); + _IF_ENQUEUE(&sc->tulip_txq, m); m = NULL; /* diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c index 56558fb..0f24ed0 100644 --- a/sys/dev/en/midway.c +++ b/sys/dev/en/midway.c @@ -1366,13 +1366,13 @@ struct en_softc *sc; continue; slot = sc->rxvc2slot[lcv]; while (1) { - IF_DEQUEUE(&sc->rxslot[slot].indma, m); + _IF_DEQUEUE(&sc->rxslot[slot].indma, m); if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); } while (1) { - IF_DEQUEUE(&sc->rxslot[slot].q, m); + _IF_DEQUEUE(&sc->rxslot[slot].q, m); if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); @@ -1393,13 +1393,13 @@ struct en_softc *sc; for (lcv = 0 ; lcv < EN_NTX ; lcv++) { while (1) { - IF_DEQUEUE(&sc->txslot[lcv].indma, m); + _IF_DEQUEUE(&sc->txslot[lcv].indma, m); if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); } while (1) { - IF_DEQUEUE(&sc->txslot[lcv].q, m); + _IF_DEQUEUE(&sc->txslot[lcv].q, m); if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); @@ -1725,7 +1725,7 @@ struct ifnet *ifp; sc->txslot[txchan].mbsize); #endif - IF_ENQUEUE(&sc->txslot[txchan].q, m); + _IF_ENQUEUE(&sc->txslot[txchan].q, m); en_txdma(sc, txchan); @@ -2093,7 +2093,7 @@ again: * it is a go, commit! dequeue mbuf start working on the xfer. */ - IF_DEQUEUE(&sc->txslot[chan].q, tmp); + _IF_DEQUEUE(&sc->txslot[chan].q, tmp); #ifdef EN_DIAG if (launch.t != tmp) panic("en dequeue"); @@ -2145,7 +2145,7 @@ again: */ sc->txslot[chan].bfree -= launch.need; - IF_ENQUEUE(&sc->txslot[chan].indma, launch.t); + _IF_ENQUEUE(&sc->txslot[chan].indma, launch.t); goto again; /* @@ -2157,7 +2157,7 @@ again: */ dequeue_drop: - IF_DEQUEUE(&sc->txslot[chan].q, tmp); + _IF_DEQUEUE(&sc->txslot[chan].q, tmp); if (launch.t != tmp) panic("en dequeue drop"); m_freem(launch.t); @@ -2624,7 +2624,7 @@ void *arg; if ((dtq = sc->dtq[idx]) != 0) { sc->dtq[idx] = 0; /* don't forget to zero it out when done */ slot = EN_DQ_SLOT(dtq); - IF_DEQUEUE(&sc->txslot[slot].indma, m); + _IF_DEQUEUE(&sc->txslot[slot].indma, m); if (!m) panic("enintr: dtqsync"); sc->txslot[slot].mbsize -= EN_DQ_LEN(dtq); #ifdef EN_DEBUG @@ -2675,7 +2675,7 @@ void *arg; if (EN_DQ_LEN(drq) == 0) { /* "JK" trash DMA? */ m = NULL; } else { - IF_DEQUEUE(&sc->rxslot[slot].indma, m); + _IF_DEQUEUE(&sc->rxslot[slot].indma, m); if (!m) panic("enintr: drqsync: %s: lost mbuf in slot %d!", sc->sc_dev.dv_xname, slot); @@ -2978,7 +2978,7 @@ defer: /* defer processing */ EN_COUNT(sc->rxqnotus); } else { EN_COUNT(sc->rxqus); - IF_DEQUEUE(&sc->rxslot[slot].q, m); + _IF_DEQUEUE(&sc->rxslot[slot].q, m); drqneed = sav[1]; #ifdef EN_DEBUG printf("%s: rx%d: recovered q'ed mbuf %p (drqneed=%d)\n", @@ -3026,7 +3026,7 @@ defer: /* defer processing */ sav = mtod(m, u_int32_t *); sav[0] = cur; sav[1] = drqneed; - IF_ENQUEUE(&sc->rxslot[slot].q, m); + _IF_ENQUEUE(&sc->rxslot[slot].q, m); EN_COUNT(sc->rxdrqout); #ifdef EN_DEBUG printf("%s: rx%d: out of DRQs\n", sc->sc_dev.dv_xname, slot); @@ -3218,7 +3218,7 @@ done: m->m_pkthdr.len -= cnt; m->m_data += cnt; } - IF_ENQUEUE(&sc->rxslot[slot].indma, m); + _IF_ENQUEUE(&sc->rxslot[slot].indma, m); } sc->rxslot[slot].cur = cur; /* update master copy of 'cur' */ diff --git a/sys/dev/hea/eni_receive.c b/sys/dev/hea/eni_receive.c index fd4eb98..8e87752 100644 --- a/sys/dev/hea/eni_receive.c +++ b/sys/dev/hea/eni_receive.c @@ -585,7 +585,7 @@ send_dma: /* * Place buffer on receive queue waiting for RX_DMA */ - if ( IF_QFULL ( &eup->eu_rxqueue ) ) { + if ( _IF_QFULL ( &eup->eu_rxqueue ) ) { /* * We haven't done anything we can't back out * of. Drop request and service it next time. @@ -605,7 +605,7 @@ send_dma: vct->vci_control &= ~VCI_IN_SERVICE; return; } else { - IF_ENQUEUE ( &eup->eu_rxqueue, m ); + _IF_ENQUEUE ( &eup->eu_rxqueue, m ); /* * Advance the RX_WR pointer to cause * the adapter to work on this DMA list. @@ -685,7 +685,7 @@ eni_recv_drain ( eup ) s = splimp(); /* Pop first buffer */ - IF_DEQUEUE ( &eup->eu_rxqueue, m ); + _IF_DEQUEUE ( &eup->eu_rxqueue, m ); while ( m ) { u_long *up; u_long pdulen; @@ -712,12 +712,12 @@ eni_recv_drain ( eup ) */ if ( start > stop ) { /* We wrapped */ if ( !(DMA_Rdptr >= stop && DMA_Rdptr < start) ) { - IF_PREPEND ( &eup->eu_rxqueue, m ); + _IF_PREPEND ( &eup->eu_rxqueue, m ); goto finish; } } else { if ( DMA_Rdptr < stop && DMA_Rdptr >= start ) { - IF_PREPEND ( &eup->eu_rxqueue, m ); + _IF_PREPEND ( &eup->eu_rxqueue, m ); goto finish; } } @@ -802,9 +802,8 @@ eni_recv_drain ( eup ) /* * Schedule callback */ - if ( !IF_QFULL ( &atm_intrq ) ) { + if (IF_HANDOFF(&atm_intrq, m, NULL)) { que++; - IF_ENQUEUE ( &atm_intrq, m ); } else { eup->eu_stats.eni_st_drv.drv_rv_intrq++; eup->eu_pif.pif_ierrors++; @@ -812,7 +811,6 @@ eni_recv_drain ( eup ) log ( LOG_ERR, "eni_receive_drain: ATM_INTRQ is full. Unable to pass up stack.\n" ); #endif - KB_FREEALL ( m ); } } else { /* @@ -825,7 +823,7 @@ next_buffer: /* * Look for next buffer */ - IF_DEQUEUE ( &eup->eu_rxqueue, m ); + _IF_DEQUEUE ( &eup->eu_rxqueue, m ); } finish: (void) splx(s); diff --git a/sys/dev/hea/eni_transmit.c b/sys/dev/hea/eni_transmit.c index 2f6f945..2fd5b24 100644 --- a/sys/dev/hea/eni_transmit.c +++ b/sys/dev/hea/eni_transmit.c @@ -271,7 +271,7 @@ eni_xmit_drain ( eup ) /* * Pull the top element (PDU) off */ - IF_DEQUEUE ( &eup->eu_txqueue, m ); + _IF_DEQUEUE ( &eup->eu_txqueue, m ); /* * As long as there are valid elements */ @@ -317,7 +317,7 @@ eni_xmit_drain ( eup ) * Haven't finished this PDU yet - replace * it as the head of list. */ - IF_PREPEND ( &eup->eu_txqueue, m ); + _IF_PREPEND ( &eup->eu_txqueue, m ); /* * If this one isn't done, none of the others * are either. @@ -331,7 +331,7 @@ eni_xmit_drain ( eup ) * Haven't finished this PDU yet - replace * it as the head of list. */ - IF_PREPEND ( &eup->eu_txqueue, m ); + _IF_PREPEND ( &eup->eu_txqueue, m ); /* * If this one isn't done, none of the others * are either. @@ -388,7 +388,7 @@ eni_xmit_drain ( eup ) /* * Look for next completed transmit PDU */ - IF_DEQUEUE ( &eup->eu_txqueue, m ); + _IF_DEQUEUE ( &eup->eu_txqueue, m ); } /* * We've drained the queue... @@ -823,7 +823,7 @@ retry: * Place buffers onto transmit queue for draining */ s2 = splimp(); - IF_ENQUEUE ( &eup->eu_txqueue, m ); + _IF_ENQUEUE ( &eup->eu_txqueue, m ); (void) splx(s2); /* diff --git a/sys/dev/hfa/fore_receive.c b/sys/dev/hfa/fore_receive.c index 0c7f4da..5b88883 100644 --- a/sys/dev/hfa/fore_receive.c +++ b/sys/dev/hfa/fore_receive.c @@ -480,12 +480,10 @@ retry: /* * Schedule callback */ - if (!IF_QFULL(&atm_intrq)) { - IF_ENQUEUE(&atm_intrq, mhead); + if (IF_HANDOFF(&atm_intrq, mhead, NULL)) { SCHED_ATM; } else { fup->fu_stats->st_drv.drv_rv_ifull++; - KB_FREEALL(mhead); goto free_ent; } diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c index c001110..fa8ffdf 100644 --- a/sys/dev/iicbus/if_ic.c +++ b/sys/dev/iicbus/if_ic.c @@ -306,11 +306,6 @@ icintr (device_t dev, int event, char *ptr) if (len <= ICHDRLEN) goto err; - if (IF_QFULL(&ipintrq)) { - IF_DROP(&ipintrq); - break; - } - len -= ICHDRLEN; sc->ic_if.if_ipackets ++; sc->ic_if.if_ibytes += len; @@ -321,8 +316,8 @@ icintr (device_t dev, int event, char *ptr) top = m_devget(sc->ic_ifbuf + ICHDRLEN, len, 0, &sc->ic_if, 0); if (top) { - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (IF_HANDOFF(&ipintrq, top, NULL)) + schednetisr(NETISR_IP); } break; diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c index b2815fe..a6c91a9 100644 --- a/sys/dev/lmc/if_lmc.c +++ b/sys/dev/lmc/if_lmc.c @@ -522,7 +522,7 @@ lmc_rx_intr(lmc_softc_t * const sc) * optimize for that case. */ if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) { - IF_DEQUEUE(&sc->lmc_rxq, ms); + _IF_DEQUEUE(&sc->lmc_rxq, ms); me = ms; } else { /* @@ -559,11 +559,11 @@ lmc_rx_intr(lmc_softc_t * const sc) * saving a ourselves from doing a multiplication * by 0 in the normal case). */ - IF_DEQUEUE(&sc->lmc_rxq, ms); + _IF_DEQUEUE(&sc->lmc_rxq, ms); for (me = ms; total_len > 0; total_len--) { me->m_len = LMC_RX_BUFLEN; last_offset += LMC_RX_BUFLEN; - IF_DEQUEUE(&sc->lmc_rxq, me->m_next); + _IF_DEQUEUE(&sc->lmc_rxq, me->m_next); me = me->m_next; } } @@ -650,7 +650,7 @@ lmc_rx_intr(lmc_softc_t * const sc) ri->ri_nextout = ri->ri_first; me = ms->m_next; ms->m_next = NULL; - IF_ENQUEUE(&sc->lmc_rxq, ms); + _IF_ENQUEUE(&sc->lmc_rxq, ms); } while ((ms = me) != NULL); if (sc->lmc_rxq.ifq_len >= LMC_RXQ_TARGET) @@ -676,7 +676,7 @@ lmc_tx_intr(lmc_softc_t * const sc) d_flag = ri->ri_nextin->d_flag; if (d_flag & TULIP_DFLAG_TxLASTSEG) { const u_int32_t d_status = ri->ri_nextin->d_status; - IF_DEQUEUE(&sc->lmc_txq, m); + _IF_DEQUEUE(&sc->lmc_txq, m); if (m != NULL) { #if NBPFILTER > 0 if (sc->lmc_bpf != NULL) @@ -994,7 +994,7 @@ lmc_txput(lmc_softc_t * const sc, struct mbuf *m) * The descriptors have been filled in. Now get ready * to transmit. */ - IF_ENQUEUE(&sc->lmc_txq, m); + _IF_ENQUEUE(&sc->lmc_txq, m); m = NULL; /* @@ -1133,6 +1133,8 @@ lmc_attach(lmc_softc_t * const sc) callout_handle_init(&sc->lmc_handle); sc->lmc_xmitq.ifq_maxlen = IFQ_MAXLEN; sc->lmc_xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->lmc_xmitq.ifq_mtx, "lmc_xmitq", MTX_DEF); + mtx_init(&sc->lmc_xmitq_hipri.ifq_mtx, "lmc_xmitq_hipri", MTX_DEF); sprintf(sc->lmc_nodename, "%s%d", NG_LMC_NODE_TYPE, sc->lmc_unit); if (ng_name_node(sc->lmc_node, sc->lmc_nodename)) { ng_rmnode(sc->lmc_node); @@ -1419,13 +1421,16 @@ ng_lmc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->lmc_xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); lmc_ifstart_one(sc); splx(s); return (0); diff --git a/sys/dev/lmc/if_lmc_common.c b/sys/dev/lmc/if_lmc_common.c index 69514cf..fabcea2 100644 --- a/sys/dev/lmc/if_lmc_common.c +++ b/sys/dev/lmc/if_lmc_common.c @@ -208,7 +208,7 @@ lmc_dec_reset(lmc_softc_t * const sc) for (;;) { struct mbuf *m; - IF_DEQUEUE(&sc->lmc_txq, m); + _IF_DEQUEUE(&sc->lmc_txq, m); if (m == NULL) break; m_freem(m); @@ -239,7 +239,7 @@ lmc_dec_reset(lmc_softc_t * const sc) } for (;;) { struct mbuf *m; - IF_DEQUEUE(&sc->lmc_rxq, m); + _IF_DEQUEUE(&sc->lmc_rxq, m); if (m == NULL) break; m_freem(m); diff --git a/sys/dev/pdq/pdq_ifsubr.c b/sys/dev/pdq/pdq_ifsubr.c index fab0c44..ac9d3d2 100644 --- a/sys/dev/pdq/pdq_ifsubr.c +++ b/sys/dev/pdq/pdq_ifsubr.c @@ -131,13 +131,7 @@ pdq_ifwatchdog( ifp->if_flags &= ~IFF_OACTIVE; ifp->if_timer = 0; - for (;;) { - struct mbuf *m; - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - return; - m_freem(m); - } + IF_DRAIN(&ifp->if_snd); } ifnet_ret_t diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c index 2410afe..ee379fe 100644 --- a/sys/dev/ppbus/if_plip.c +++ b/sys/dev/ppbus/if_plip.c @@ -513,11 +513,6 @@ lp_intr (void *arg) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf("DROP"); - IF_DROP(&ipintrq); - goto done; - } len -= CLPIPHDRLEN; sc->sc_if.if_ipackets++; sc->sc_if.if_ibytes += len; @@ -525,8 +520,11 @@ lp_intr (void *arg) if (top) { if (sc->sc_if.if_bpf) lptap(&sc->sc_if, top); - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) { + lprintf("DROP"); + } else { + schednetisr(NETISR_IP); + } } goto done; } @@ -564,11 +562,6 @@ lp_intr (void *arg) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf("DROP"); - IF_DROP(&ipintrq); - goto done; - } len -= LPIPHDRLEN; sc->sc_if.if_ipackets++; sc->sc_if.if_ibytes += len; @@ -576,8 +569,11 @@ lp_intr (void *arg) if (top) { if (sc->sc_if.if_bpf) lptap(&sc->sc_if, top); - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) { + lprintf("DROP"); + } else { + schednetisr(NETISR_IP); + } } } goto done; diff --git a/sys/dev/sr/if_sr.c b/sys/dev/sr/if_sr.c index 9af963b..89b2c99 100644 --- a/sys/dev/sr/if_sr.c +++ b/sys/dev/sr/if_sr.c @@ -941,6 +941,8 @@ srattach(struct sr_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "sr_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "sr_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_SR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -3264,13 +3266,16 @@ ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); srstart(sc); splx(s); return (0); diff --git a/sys/dev/sr/if_sr_isa.c b/sys/dev/sr/if_sr_isa.c index 9af963b..89b2c99 100644 --- a/sys/dev/sr/if_sr_isa.c +++ b/sys/dev/sr/if_sr_isa.c @@ -941,6 +941,8 @@ srattach(struct sr_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "sr_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "sr_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_SR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -3264,13 +3266,16 @@ ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); srstart(sc); splx(s); return (0); diff --git a/sys/dev/usb/udbp.c b/sys/dev/usb/udbp.c index 71eb710..d75e1f2 100644 --- a/sys/dev/usb/udbp.c +++ b/sys/dev/usb/udbp.c @@ -359,6 +359,8 @@ USB_ATTACH(udbp) sc->node->private = sc; sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "usb_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "usb_xmitq_hipri", MTX_DEF); sprintf(nodename, "%s", USBDEVNAME(sc->sc_dev)); if ((err = ng_name_node(sc->node, nodename))) { ng_rmnode(sc->node); @@ -737,13 +739,16 @@ ng_udbp_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splusb(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); if (!(sc->flags & OUT_BUSY)) udbp_setup_out_transfer(sc); splx(s); @@ -772,16 +777,8 @@ ng_udbp_rmnode(node_p node) ng_cutlinks(node); /* Drain the queues */ - do { - IF_DEQUEUE(&sc->xmitq_hipri, m); - if (m) - m_freem(m); - } while (m); - do { - IF_DEQUEUE(&sc->xmitq, m); - if (m) - m_freem(m); - } while (m); + IF_DRAIN(&sc->xmitq_hipri); + IF_DRAIN(&sc->xmitq); sc->packets_in = 0; /* reset stats */ sc->packets_out = 0; diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c index c02ed7d..3065c47 100644 --- a/sys/dev/usb/usb_ethersubr.c +++ b/sys/dev/usb/usb_ethersubr.c @@ -73,9 +73,7 @@ Static const char rcsid[] = #endif Static struct ifqueue usbq_rx; -Static struct mtx usbq_rx_mtx; Static struct ifqueue usbq_tx; -Static struct mtx usbq_tx_mtx; Static int mtx_inited = 0; Static void usbintr __P((void)); @@ -89,9 +87,7 @@ Static void usbintr() /* Check the RX queue */ while(1) { - mtx_enter(&usbq_rx_mtx, MTX_DEF); IF_DEQUEUE(&usbq_rx, m); - mtx_exit(&usbq_rx_mtx, MTX_DEF); if (m == NULL) break; eh = mtod(m, struct ether_header *); @@ -109,9 +105,7 @@ Static void usbintr() /* Check the TX queue */ while(1) { - mtx_enter(&usbq_tx_mtx, MTX_DEF); IF_DEQUEUE(&usbq_tx, m); - mtx_exit(&usbq_tx_mtx, MTX_DEF); if (m == NULL) break; ifp = m->m_pkthdr.rcvif; @@ -128,8 +122,8 @@ void usb_register_netisr() if (mtx_inited) return; register_netisr(NETISR_USB, usbintr); - mtx_init(&usbq_tx_mtx, "usbq_tx_mtx", MTX_DEF); - mtx_init(&usbq_rx_mtx, "usbq_rx_mtx", MTX_DEF); + mtx_init(&usbq_tx.ifq_mtx, "usbq_tx_mtx", MTX_DEF); + mtx_init(&usbq_rx.ifq_mtx, "usbq_rx_mtx", MTX_DEF); mtx_inited++; return; } @@ -141,9 +135,7 @@ void usb_register_netisr() void usb_ether_input(m) struct mbuf *m; { - mtx_enter(&usbq_rx_mtx, MTX_DEF); IF_ENQUEUE(&usbq_rx, m); - mtx_exit(&usbq_rx_mtx, MTX_DEF); schednetisr(NETISR_USB); return; @@ -152,9 +144,7 @@ void usb_ether_input(m) void usb_tx_done(m) struct mbuf *m; { - mtx_enter(&usbq_tx_mtx, MTX_DEF); IF_ENQUEUE(&usbq_tx, m); - mtx_exit(&usbq_tx_mtx, MTX_DEF); schednetisr(NETISR_USB); return; diff --git a/sys/i386/isa/if_ar.c b/sys/i386/isa/if_ar.c index f43aef1..dfbc3ac 100644 --- a/sys/i386/isa/if_ar.c +++ b/sys/i386/isa/if_ar.c @@ -515,6 +515,8 @@ arattach(struct ar_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "ar_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "ar_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -2308,13 +2310,16 @@ ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); arstart(sc); splx(s); return (0); diff --git a/sys/i386/isa/if_sr.c b/sys/i386/isa/if_sr.c index 9af963b..89b2c99 100644 --- a/sys/i386/isa/if_sr.c +++ b/sys/i386/isa/if_sr.c @@ -941,6 +941,8 @@ srattach(struct sr_hardc *hc) callout_handle_init(&sc->handle); sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "sr_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "sr_xmitq_hipri", MTX_DEF); sprintf(sc->nodename, "%s%d", NG_SR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { ng_rmnode(sc->node); @@ -3264,13 +3266,16 @@ ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, xmitq_p = (&sc->xmitq); } s = splimp(); - if (IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); error = ENOBUFS; goto bad; } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); srstart(sc); splx(s); return (0); diff --git a/sys/i4b/driver/i4b_bsdi_ibc.c b/sys/i4b/driver/i4b_bsdi_ibc.c index 369d4aa..6fcfe4c 100644 --- a/sys/i4b/driver/i4b_bsdi_ibc.c +++ b/sys/i4b/driver/i4b_bsdi_ibc.c @@ -196,18 +196,11 @@ ibcattach(void *dummy) static struct mbuf * p2p_dequeue(struct p2pcom *pp) { - struct ifqueue *ifq; struct mbuf *m; - ifq = &pp->p2p_isnd; - m = ifq->ifq_head; - if (m == 0) { - ifq = &pp->p2p_if.if_snd; - m = ifq->ifq_head; - } + IF_DEQUEUE(&pp->p2p_isnd, m); if (m == 0) - return 0; - IF_DEQUEUE(ifq, m); + IF_DEQUEUE(&pp->p2p_if.if_snd, m); return m; } @@ -231,13 +224,16 @@ ibc_start(struct ifnet *ifp) s = SPLI4B(); - if (IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) { + IF_LOCK(isdn_ibc_lt[unit]->tx_queue); + if (_IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) { + IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue); splx(s); return 0; } m = p2p_dequeue(pp); if (m == NULL) { + IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue); splx(s); return 0; } @@ -245,13 +241,14 @@ ibc_start(struct ifnet *ifp) do { microtime(&ifp->if_lastchange); - IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m); - ifp->if_obytes += m->m_pkthdr.len; sc->sc_outb += m->m_pkthdr.len; + _IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m); + ifp->if_opackets++; - } while (!IF_QFULL(isdn_ibc_lt[unit]->tx_queue) && + } while (!_IF_QFULL(isdn_ibc_lt[unit]->tx_queue) && (m = p2p_dequeue(pp)) != NULL); + IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue); isdn_ibc_lt[unit]->bch_tx_start(isdn_ibc_lt[unit]->unit, isdn_ibc_lt[unit]->channel); splx(s); diff --git a/sys/i4b/driver/i4b_ing.c b/sys/i4b/driver/i4b_ing.c index 26a5b3b..50e1c4b 100644 --- a/sys/i4b/driver/i4b_ing.c +++ b/sys/i4b/driver/i4b_ing.c @@ -247,6 +247,7 @@ i4bingattach(void *dummy) sc->sc_state = ST_IDLE; sc->sc_fastq.ifq_maxlen = I4BINGMAXQLEN; + mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ing_fastq", MTX_DEF); #if I4BINGACCT callout_handle_init(&sc->sc_callout); @@ -278,6 +279,8 @@ i4bingattach(void *dummy) sc->xmitq.ifq_maxlen = IFQ_MAXLEN; sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->xmitq.ifq_mtx, "i4b_ing_xmitq", MTX_DEF); + mtx_init(&sc->xmitq_hipri.ifq_mtx, "i4b_ing_hipri", MTX_DEF); /* name the netgraph node */ @@ -339,20 +342,11 @@ static void ingclearqueue(struct ifqueue *iq) { int x; - struct mbuf *m; - for(;;) - { - x = splimp(); - IF_DEQUEUE(iq, m); - splx(x); - - if(m) - m_freem(m); - else - break; - } -} + x = splimp(); + IF_DRAIN(iq); + splx(x); +} #endif /*===========================================================================* @@ -517,14 +511,9 @@ ing_tx_queue_empty(int unit) x = 1; - if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + if(! IF_HANDOFF(isdn_linktab[unit]->tx_queue, m, NULL)) { NDBGL4(L4_INGDBG, "ing%d: tx queue full!", unit); - m_freem(m); - } - else - { - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); } } @@ -794,15 +783,18 @@ ng_ing_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) s = splimp(); - if (IF_QFULL(xmitq_p)) + IF_LOCK(xmitq_p); + if (_IF_QFULL(xmitq_p)) { - IF_DROP(xmitq_p); + _IF_DROP(xmitq_p); + IF_UNLOCK(xmitq_p); splx(s); NG_FREE_DATA(m, meta); return(ENOBUFS); } - IF_ENQUEUE(xmitq_p, m); + _IF_ENQUEUE(xmitq_p, m); + IF_UNLOCK(xmitq_p); ing_tx_queue_empty(sc->sc_unit); diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c index 4d76cb9..4aa074a 100644 --- a/sys/i4b/driver/i4b_ipr.c +++ b/sys/i4b/driver/i4b_ipr.c @@ -324,6 +324,7 @@ i4biprattach() sc->sc_if.if_snd.ifq_maxlen = I4BIPRMAXQLEN; sc->sc_fastq.ifq_maxlen = I4BIPRMAXQLEN; + mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ipr_fastq", MTX_DEF); sc->sc_if.if_ipackets = 0; sc->sc_if.if_ierrors = 0; @@ -509,11 +510,9 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, /* check for space in choosen send queue */ - if(IF_QFULL(ifq)) + if(! IF_HANDOFF(ifq, m, NULL)) { NDBGL4(L4_IPRDBG, "ipr%d: send queue full!", unit); - IF_DROP(ifq); - m_freem(m); splx(s); sc->sc_if.if_oerrors++; return(ENOBUFS); @@ -521,8 +520,6 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, NDBGL4(L4_IPRDBG, "ipr%d: add packet to send queue!", unit); - IF_ENQUEUE(ifq, m); - ipr_tx_queue_empty(unit); splx(s); @@ -648,31 +645,11 @@ static void iprclearqueues(struct ipr_softc *sc) { int x; - struct mbuf *m; - for(;;) - { - x = splimp(); - IF_DEQUEUE(&sc->sc_fastq, m); - splx(x); - - if(m) - m_freem(m); - else - break; - } - - for(;;) - { - x = splimp(); - IF_DEQUEUE(&sc->sc_if.if_snd, m); - splx(x); - - if(m) - m_freem(m); - else - break; - } + x = splimp(); + IF_DRAIN(&sc->sc_fastq); + IF_DRAIN(&sc->sc_if.if_snd); + splx(x); } #if I4BIPRACCT @@ -1070,18 +1047,14 @@ error: } #endif /* NBPFILTER > 0 || NBPF > 0 */ - if(IF_QFULL(&ipintrq)) + if(! IF_HANDOFF(&ipintrq, m, NULL)) { NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit); - - IF_DROP(&ipintrq); sc->sc_if.if_ierrors++; sc->sc_if.if_iqdrops++; - m_freem(m); } else { - IF_ENQUEUE(&ipintrq, m); schednetisr(NETISR_IP); } } @@ -1155,19 +1128,22 @@ ipr_tx_queue_empty(int unit) #endif x = 1; - if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + IF_LOCK(isdn_linktab[unit]->tx_queue); + if(_IF_QFULL(isdn_linktab[unit]->tx_queue)) { NDBGL4(L4_IPRDBG, "ipr%d: tx queue full!", unit); m_freem(m); } else { - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); - sc->sc_if.if_obytes += m->m_pkthdr.len; sc->sc_if.if_opackets++; + + _IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); + } + IF_UNLOCK(isdn_linktab[unit]->tx_queue); } if(x) diff --git a/sys/i4b/driver/i4b_isppp.c b/sys/i4b/driver/i4b_isppp.c index f13c229..0be5efa 100644 --- a/sys/i4b/driver/i4b_isppp.c +++ b/sys/i4b/driver/i4b_isppp.c @@ -426,20 +426,23 @@ i4bisppp_start(struct ifnet *ifp) microtime(&ifp->if_lastchange); - if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + IF_LOCK(isdn_linktab[unit]->tx_queue); + if(_IF_QFULL(isdn_linktab[unit]->tx_queue)) { NDBGL4(L4_ISPDBG, "isp%d, tx queue full!", unit); m_freem(m); } else { - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); #if 0 sc->sc_if.if_obytes += m->m_pkthdr.len; #endif sc->sc_outb += m->m_pkthdr.len; sc->sc_if.if_opackets++; + + _IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); } + IF_UNLOCK(isdn_linktab[unit]->tx_queue); } isdn_linktab[unit]->bch_tx_start(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel); diff --git a/sys/i4b/driver/i4b_ispppsubr.c b/sys/i4b/driver/i4b_ispppsubr.c index 7b3a1f9..cbe45b6 100644 --- a/sys/i4b/driver/i4b_ispppsubr.c +++ b/sys/i4b/driver/i4b_ispppsubr.c @@ -665,17 +665,15 @@ isppp_input(struct ifnet *ifp, struct mbuf *m) /* Check queue. */ s = splimp(); - if (IF_QFULL (inq)) { - /* Queue overflow. */ - IF_DROP(inq); - splx(s); + if (! IF_HANDOFF(inq, m, NULL)) { + ++ifp->if_ierrors; + ++ifp->if_iqdrops; if (debug) log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", SPP_ARGS(ifp)); - goto drop; + } else { + sp->pp_last_recv = time_second; } - IF_ENQUEUE(inq, m); - sp->pp_last_recv = time_second; splx(s); } @@ -748,7 +746,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, * Put low delay, telnet, rlogin and ftp control packets * in front of the queue. */ - if (IF_QFULL (&sp->pp_fastq)) + if (_IF_QFULL (&sp->pp_fastq)) ; else if (ip->ip_tos & IPTOS_LOWDELAY) ifq = &sp->pp_fastq; @@ -870,24 +868,17 @@ nosupport: /* * Queue message on interface, and start output if interface * not yet active. + * + * Count output packets and bytes. + * The packet length includes header, FCS and 1 flag, + * according to RFC 1333. */ - if (IF_QFULL (ifq)) { - IF_DROP (&ifp->if_snd); - m_freem (m); + if (! IF_HANDOFF_ADJ(ifq, m, ifp, 3)) { ++ifp->if_oerrors; splx (s); return (rv? rv: ENOBUFS); } - IF_ENQUEUE (ifq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - /* - * Count output packets and bytes. - * The packet length includes header, FCS and 1 flag, - * according to RFC 1333. - */ - ifp->if_obytes += m->m_pkthdr.len + 3; sp->pp_last_sent = time_second; splx (s); return (0); @@ -921,6 +912,8 @@ isppp_attach(struct ifnet *ifp) sp->pp_fastq.ifq_maxlen = 32; sp->pp_cpq.ifq_maxlen = 20; + mtx_init(&sp->pp_fastq.ifq_mtx, "i4b_isppp_fastq", MTX_DEF); + mtx_init(&sp->pp_cpq.ifq_mtx, "i4b_isppp_cpq", MTX_DEF); sp->pp_loopcnt = 0; sp->pp_alivecnt = 0; sp->pp_seq = 0; @@ -1316,15 +1309,7 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2) SPP_ARGS(ifp), (u_long)ntohl (ch->type), (u_long)ch->par1, (u_long)ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1); - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; + (void) IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3); } /* @@ -1372,16 +1357,8 @@ sppp_cp_send(struct sppp *sp, u_short proto, u_char type, sppp_print_bytes ((u_char*) (lh+1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); + if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) ++ifp->if_oerrors; - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; } /* @@ -4035,16 +4012,8 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, sppp_print_bytes((u_char*) (lh+1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); + if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, NULL, 3)) ++ifp->if_oerrors; - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; } /* diff --git a/sys/i4b/driver/i4b_rbch.c b/sys/i4b/driver/i4b_rbch.c index 59247c2..9e7db6a 100644 --- a/sys/i4b/driver/i4b_rbch.c +++ b/sys/i4b/driver/i4b_rbch.c @@ -327,6 +327,7 @@ i4brbchattach() rbch_softc[i].sc_unit = i; rbch_softc[i].sc_devstate = ST_IDLE; rbch_softc[i].sc_hdlcq.ifq_maxlen = I4BRBCHMAXQLEN; + mtx_init(&rbch_softc[i].sc_hdlcq.ifq_mtx, "i4b_rbch", MTX_DEF); rbch_softc[i].it_in.c_ispeed = rbch_softc[i].it_in.c_ospeed = 64000; termioschars(&rbch_softc[i].it_in); rbch_init_linktab(i); @@ -510,7 +511,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) CRIT_END; return(EWOULDBLOCK); } - if(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) { + if(_IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) { CRIT_END; return(EWOULDBLOCK); } @@ -543,7 +544,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) tsleep((caddr_t) &rbch_softc[unit], TTIPRI | PCATCH, "xrbch", (hz*1)); } - while(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) + while(_IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) { sc->sc_devstate |= ST_WRWAITEMPTY; @@ -589,15 +590,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) error = uiomove(m->m_data, m->m_len, uio); - if(IF_QFULL(isdn_linktab[unit]->tx_queue)) - { - m_freem(m); - } - else - { - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); - } - + (void) IF_HANDOFF(isdn_linktab[unit]->tx_queue, m, NULL); (*isdn_linktab[unit]->bch_tx_start)(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel); } @@ -733,7 +726,7 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) if((events & (POLLOUT|POLLWRNORM)) && (sc->sc_devstate & ST_CONNECTED) && - !IF_QFULL(isdn_linktab[unit]->tx_queue)) + !_IF_QFULL(isdn_linktab[unit]->tx_queue)) { revents |= (events & (POLLOUT|POLLWRNORM)); } @@ -802,7 +795,7 @@ i4brbchselect(dev_t dev, int rw, struct proc *p) break; case FWRITE: - if(!IF_QFULL(isdn_linktab[unit]->rx_queue)) + if(!_IF_QFULL(isdn_linktab[unit]->rx_queue)) { splx(s); return(1); @@ -962,16 +955,11 @@ rbch_rx_data_rdy(int unit) m->m_pkthdr.len = m->m_len; - if(IF_QFULL(&(rbch_softc[unit].sc_hdlcq))) + if (! IF_HANDOFF(&(rbch_softc[unit].sc_hdlcq), m, NULL)) { NDBGL4(L4_RBCHDBG, "unit %d: hdlc rx queue full!", unit); - m_freem(m); } - else - { - IF_ENQUEUE(&(rbch_softc[unit].sc_hdlcq), m); - } - } + } if(rbch_softc[unit].sc_devstate & ST_RDWAITDATA) { @@ -1025,20 +1013,11 @@ rbch_activity(int unit, int rxtx) static void rbch_clrq(int unit) { - struct mbuf *m; CRIT_VAR; - for(;;) - { - CRIT_BEG; - IF_DEQUEUE(&rbch_softc[unit].sc_hdlcq, m); - CRIT_END; - - if(m) - m_freem(m); - else - break; - } + CRIT_BEG; + IF_DRAIN(&rbch_softc[unit].sc_hdlcq); + CRIT_END; } /*---------------------------------------------------------------------------* diff --git a/sys/i4b/driver/i4b_tel.c b/sys/i4b/driver/i4b_tel.c index 1652b20..b34ec16 100644 --- a/sys/i4b/driver/i4b_tel.c +++ b/sys/i4b/driver/i4b_tel.c @@ -573,6 +573,7 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag) if(func == FUNCTEL) { s = splimp(); + IF_LOCK(sc->isdn_linktab->rx_queue); while(IF_QEMPTY(sc->isdn_linktab->rx_queue) && (sc->devstate & ST_ISOPEN) && (sc->devstate & ST_CONNECTED)) @@ -581,11 +582,13 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag) NDBGL4(L4_TELDBG, "i4btel%d, queue empty!", unit); - if((error = tsleep((caddr_t) &sc->isdn_linktab->rx_queue, + if((error = msleep((caddr_t) &sc->isdn_linktab->rx_queue, + &sc->isdn_linktab->rx_queue->ifq_mtx, TTIPRI | PCATCH, "rtel", 0 )) != 0) { sc->devstate &= ~ST_RDWAITDATA; + IF_UNLOCK(sc->isdn_linktab->rx_queue); splx(s); return(error); } @@ -593,18 +596,21 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag) if(!(sc->devstate & ST_ISOPEN)) { + IF_UNLOCK(sc->isdn_linktab->rx_queue); splx(s); return(EIO); } if(!(sc->devstate & ST_CONNECTED)) { + IF_UNLOCK(sc->isdn_linktab->rx_queue); splx(s); return(EIO); } - IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); + _IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); + IF_UNLOCK(sc->isdn_linktab->rx_queue); if(m && m->m_len > 0) { @@ -700,19 +706,23 @@ i4btelwrite(dev_t dev, struct uio * uio, int ioflag) } sc->devstate &= ~ST_TONE; - while((IF_QFULL(sc->isdn_linktab->tx_queue)) && + IF_LOCK(sc->isdn_linktab->tx_queue); + while((_IF_QFULL(sc->isdn_linktab->tx_queue)) && (sc->devstate & ST_ISOPEN)) { sc->devstate |= ST_WRWAITEMPTY; - if((error = tsleep((caddr_t) &sc->isdn_linktab->tx_queue, + if((error = msleep((caddr_t) &sc->isdn_linktab->tx_queue, + &sc->isdn_linktab->tx_queue->ifq_mtx, TTIPRI | PCATCH, "wtel", 0)) != 0) { sc->devstate &= ~ST_WRWAITEMPTY; + IF_UNLOCK(sc->isdn_linktab->tx_queue); splx(s); return(error); } } + IF_UNLOCK(sc->isdn_linktab->tx_queue); if(!(sc->devstate & ST_ISOPEN)) { @@ -744,15 +754,7 @@ i4btelwrite(dev_t dev, struct uio * uio, int ioflag) mtod(m,u_char *)[i] = bitreverse[mtod(m,u_char *)[i]]; } - if(IF_QFULL(sc->isdn_linktab->tx_queue)) - { - m_freem(m); - } - else - { - IF_ENQUEUE(sc->isdn_linktab->tx_queue, m); - } - + (void) IF_HANDOFF(sc->isdn_linktab->tx_queue, m, NULL); (*sc->isdn_linktab->bch_tx_start)(sc->isdn_linktab->unit, sc->isdn_linktab->channel); } @@ -867,7 +869,7 @@ i4btelpoll(dev_t dev, int events, struct proc *p) if((events & (POLLOUT|POLLWRNORM)) && (sc->devstate & ST_CONNECTED) && (sc->isdn_linktab != NULL) && - (!IF_QFULL(sc->isdn_linktab->tx_queue))) + (!_IF_QFULL(sc->isdn_linktab->tx_queue))) { NDBGL4(L4_TELDBG, "i4btel%d, POLLOUT", unit); revents |= (events & (POLLOUT|POLLWRNORM)); @@ -958,7 +960,7 @@ i4btelsel(dev_t dev, int rw, struct proc *p) } else if (rw == FWRITE) { - if (!IF_QFULL(sc->isdn_linktab->tx_queue)) + if (!_IF_QFULL(sc->isdn_linktab->tx_queue)) { NDBGL4(L4_TELDBG, "i4btel%d, FWRITE", unit); splx(s); diff --git a/sys/i4b/driver/i4b_trace.c b/sys/i4b/driver/i4b_trace.c index 0d10771..ff29c01 100644 --- a/sys/i4b/driver/i4b_trace.c +++ b/sys/i4b/driver/i4b_trace.c @@ -245,6 +245,7 @@ i4btrcattach() #endif #endif trace_queue[i].ifq_maxlen = IFQ_MAXLEN; + mtx_init(&trace_queue[i].ifq_mtx, "i4b_trace", MTX_DEF); device_state[i] = ST_IDLE; } } @@ -317,12 +318,13 @@ get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf) unit = outunit; } - if(IF_QFULL(&trace_queue[unit])) + IF_LOCK(&trace_queue[unit]); + if(_IF_QFULL(&trace_queue[unit])) { struct mbuf *m1; x = SPLI4B(); - IF_DEQUEUE(&trace_queue[unit], m1); + _IF_DEQUEUE(&trace_queue[unit], m1); splx(x); i4b_Bfreembuf(m1); @@ -339,7 +341,8 @@ get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf) x = SPLI4B(); - IF_ENQUEUE(&trace_queue[unit], m); + _IF_ENQUEUE(&trace_queue[unit], m); + IF_UNLOCK(&trace_queue[unit]); if(device_state[unit] & ST_WAITDATA) { @@ -441,21 +444,25 @@ i4btrcread(dev_t dev, struct uio * uio, int ioflag) x = SPLI4B(); + IF_LOCK(&trace_queue[unit]); while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN)) { device_state[unit] |= ST_WAITDATA; - if((error = tsleep((caddr_t) &trace_queue[unit], + if((error = msleep((caddr_t) &trace_queue[unit], + &trace_queue[unit].ifq_mtx, TTIPRI | PCATCH, "bitrc", 0 )) != 0) { device_state[unit] &= ~ST_WAITDATA; + IF_UNLOCK(&trace_queue[unit]); splx(x); return(error); } } - IF_DEQUEUE(&trace_queue[unit], m); + _IF_DEQUEUE(&trace_queue[unit], m); + IF_UNLOCK(&trace_queue[unit]); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, uio); diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c index a59e07d..6fb3c11 100644 --- a/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c +++ b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c @@ -863,14 +863,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc) /* move rx'd data to rx queue */ - if (!(IF_QFULL(&chan->rx_queue))) - { - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - } - else - { - i4b_Bfreembuf(chan->in_mbuf); - } + (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL); /* signal upper layer that data are available */ (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); @@ -1124,9 +1117,10 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* receiver part */ - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->rx_queue.ifq_mtx, "i4b_avma1pp_rx", MTX_DEF); + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ chan->rxcount = 0; /* reset rx counter */ @@ -1138,10 +1132,11 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* transmitter part */ - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->tx_queue.ifq_mtx, "i4b_avma1pp_tx", MTX_DEF); + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + chan->txcount = 0; /* reset tx counter */ i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c index 401a19d..bc69399 100644 --- a/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c +++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c @@ -799,14 +799,7 @@ avm_pnp_hscx_intr(int h_chan, u_int stat, u_int cnt, struct l1_softc *sc) /* move rx'd data to rx queue */ - if (!(IF_QFULL(&chan->rx_queue))) - { - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - } - else - { - i4b_Bfreembuf(chan->in_mbuf); - } + (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL); /* signal upper layer that data are available */ (*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit); @@ -1044,9 +1037,10 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* receiver part */ - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->rx_queue.ifq_mtx, "i4b_avm_pnp_rx", MTX_DEF); + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ chan->rxcount = 0; /* reset rx counter */ @@ -1058,10 +1052,11 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* transmitter part */ + chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->tx_queue.ifq_mtx, "i4b_avm_pnp_tx", MTX_DEF); + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; - chan->txcount = 0; /* reset tx counter */ i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c index 814a40a..7a01014 100644 --- a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c @@ -351,13 +351,14 @@ ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate) do { if (chan < 2) /* D-Channel */ { + S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&S_IFQUEUE.ifq_mtx, "i4b_ihfc", MTX_DEF); + i4b_Dfreembuf(S_MBUF); i4b_Dcleanifq(&S_IFQUEUE); RESET_SOFT_CHAN(sc, chan); - S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; - if (!activate) continue; if (S_HFC & HFC_1) @@ -373,13 +374,15 @@ ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate) } else /* B-Channel */ { + S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&S_IFQUEUE.ifq_mtx, "i4b_ihfc", MTX_DEF); + i4b_Bfreembuf(S_MBUF); i4b_Bcleanifq(&S_IFQUEUE); RESET_SOFT_CHAN(sc, chan); S_PROT = prot; - S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN; if (!activate) continue; diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c index 5b9e6cf..4bb59f0 100644 --- a/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c +++ b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c @@ -127,7 +127,7 @@ ihfc_ph_data_req(int unit, struct mbuf *m, int freeflag) if (freeflag == MBUF_DONTFREE) m = m_copypacket(m, M_DONTWAIT); - if (!IF_QFULL(&S_IFQUEUE) && m) + if (!_IF_QFULL(&S_IFQUEUE) && m) { IF_ENQUEUE(&S_IFQUEUE, m); @@ -300,7 +300,7 @@ ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m) S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_RX); } - if (!IF_QFULL(&S_IFQUEUE)) + if (!_IF_QFULL(&S_IFQUEUE)) { S_BYTES += m->m_len; IF_ENQUEUE(&S_IFQUEUE, m); diff --git a/sys/i4b/layer1/isic/i4b_bchan.c b/sys/i4b/layer1/isic/i4b_bchan.c index f1db0ea..c937790 100644 --- a/sys/i4b/layer1/isic/i4b_bchan.c +++ b/sys/i4b/layer1/isic/i4b_bchan.c @@ -91,9 +91,10 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* receiver part */ - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->rx_queue.ifq_mtx, "i4b_isic_rx", MTX_DEF); + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ chan->rxcount = 0; /* reset rx counter */ @@ -105,10 +106,11 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* transmitter part */ - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->tx_queue.ifq_mtx, "i4b_isic_tx", MTX_DEF); + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + chan->txcount = 0; /* reset tx counter */ i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ diff --git a/sys/i4b/layer1/isic/i4b_hscx.c b/sys/i4b/layer1/isic/i4b_hscx.c index 121b8c5..79e74b8 100644 --- a/sys/i4b/layer1/isic/i4b_hscx.c +++ b/sys/i4b/layer1/isic/i4b_hscx.c @@ -270,14 +270,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) activity = ACT_RX; - if(!(IF_QFULL(&chan->rx_queue))) - { - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - } - else - { - i4b_Bfreembuf(chan->in_mbuf); - } + (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL); /* signal upper driver that data is available */ diff --git a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c index e836f78..0b8fa26 100644 --- a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c +++ b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c @@ -239,14 +239,7 @@ iwic_bchan_xirq(struct iwic_softc *sc, int chan_no) if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) activity = ACT_RX; - if(!(IF_QFULL(&chan->rx_queue))) - { - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); - } - else - { - i4b_Bfreembuf(chan->in_mbuf); - } + (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL); /* signal upper driver that data is available */ @@ -416,9 +409,10 @@ iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate) /* receiver part */ - i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ - chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->rx_queue.ifq_mtx, "i4b_iwic_rx", MTX_DEF); + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ chan->rxcount = 0; /* reset rx counter */ @@ -430,9 +424,10 @@ iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate) /* transmitter part */ - i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ - chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&chan->tx_queue.ifq_mtx, "i4b_iwic_tx", MTX_DEF); + + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ chan->txcount = 0; /* reset tx counter */ diff --git a/sys/i4b/layer2/i4b_l2.c b/sys/i4b/layer2/i4b_l2.c index 59a09ba..b3f79a6 100644 --- a/sys/i4b/layer2/i4b_l2.c +++ b/sys/i4b/layer2/i4b_l2.c @@ -163,7 +163,7 @@ int i4b_dl_data_req(int unit, struct mbuf *m) case ST_MULTIFR: case ST_TIMREC: - if(IF_QFULL(&l2sc->i_queue)) + if(_IF_QFULL(&l2sc->i_queue)) { NDBGL2(L2_ERROR, "i_queue full!!"); i4b_Dfreembuf(m); @@ -277,6 +277,7 @@ i4b_mph_status_ind(int unit, int status, int parm) case STI_ATTACH: l2sc->unit = unit; l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN; + mtx_init(&l2sc->i_queue.ifq_mtx, "i4b_l2sc", MTX_DEF); l2sc->ua_frame = NULL; bzero(&l2sc->stat, sizeof(lapdstat_t)); i4b_l2_unit_init(unit); diff --git a/sys/i4b/layer2/i4b_mbuf.c b/sys/i4b/layer2/i4b_mbuf.c index a0f1013..0537a5e 100644 --- a/sys/i4b/layer2/i4b_mbuf.c +++ b/sys/i4b/layer2/i4b_mbuf.c @@ -140,15 +140,9 @@ i4b_Dfreembuf(struct mbuf *m) void i4b_Dcleanifq(struct ifqueue *ifq) { - struct mbuf *m; int x = splimp(); - while(!IF_QEMPTY(ifq)) - { - IF_DEQUEUE(ifq, m); - i4b_Dfreembuf(m); - } - + IF_DRAIN(ifq); splx(x); } @@ -222,15 +216,9 @@ i4b_Bfreembuf(struct mbuf *m) void i4b_Bcleanifq(struct ifqueue *ifq) { - struct mbuf *m; int x = splimp(); - while(!IF_QEMPTY(ifq)) - { - IF_DEQUEUE(ifq, m); - i4b_Bfreembuf(m); - } - + IF_DRAIN(ifq); splx(x); } diff --git a/sys/i4b/layer2/i4b_util.c b/sys/i4b/layer2/i4b_util.c index 982760d..0569a84 100644 --- a/sys/i4b/layer2/i4b_util.c +++ b/sys/i4b/layer2/i4b_util.c @@ -182,7 +182,7 @@ i4b_invoke_retransmission(l2_softc_t *l2sc, int nr) if((l2sc->ua_num != UA_EMPTY) && (l2sc->vs == l2sc->ua_num)) { - if(IF_QFULL(&l2sc->i_queue)) + if(_IF_QFULL(&l2sc->i_queue)) { NDBGL2(L2_ERROR, "ERROR, I-queue full!"); } diff --git a/sys/i4b/layer4/i4b_i4bdrv.c b/sys/i4b/layer4/i4b_i4bdrv.c index d02a159..118926d 100644 --- a/sys/i4b/layer4/i4b_i4bdrv.c +++ b/sys/i4b/layer4/i4b_i4bdrv.c @@ -262,6 +262,7 @@ i4battach() printf("i4b: ISDN call control device attached\n"); #endif i4b_rdqueue.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&i4b_rdqueue.ifq_mtx, "i4b_rdqueue", MTX_DEF); #if defined(__FreeBSD__) #if __FreeBSD__ == 3 @@ -328,17 +329,21 @@ i4bread(dev_t dev, struct uio *uio, int ioflag) return(ENODEV); x = splimp(); + IF_LOCK(&i4b_rdqueue); while(IF_QEMPTY(&i4b_rdqueue)) { readflag = 1; - error = tsleep((caddr_t) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0); + error = msleep((caddr_t) &i4b_rdqueue, &i4b_rdqueue.ifq_mtx, + (PZERO + 1) | PCATCH, "bird", 0); if (error != 0) { - splx(x); + IF_UNLOCK(&i4b_rdqueue); + splx(x); return error; } } - IF_DEQUEUE(&i4b_rdqueue, m); + _IF_DEQUEUE(&i4b_rdqueue, m); + IF_UNLOCK(&i4b_rdqueue); splx(x); @@ -978,15 +983,17 @@ i4bputqueue(struct mbuf *m) x = splimp(); - if(IF_QFULL(&i4b_rdqueue)) + IF_LOCK(&i4b_rdqueue); + if(_IF_QFULL(&i4b_rdqueue)) { struct mbuf *m1; - IF_DEQUEUE(&i4b_rdqueue, m1); + _IF_DEQUEUE(&i4b_rdqueue, m1); i4b_Dfreembuf(m1); NDBGL4(L4_ERR, "ERROR, queue full, removing entry!"); } - IF_ENQUEUE(&i4b_rdqueue, m); + _IF_ENQUEUE(&i4b_rdqueue, m); + IF_UNLOCK(&i4b_rdqueue); splx(x); @@ -1019,15 +1026,17 @@ i4bputqueue_hipri(struct mbuf *m) x = splimp(); - if(IF_QFULL(&i4b_rdqueue)) + IF_LOCK(&i4b_rdqueue); + if(_IF_QFULL(&i4b_rdqueue)) { struct mbuf *m1; - IF_DEQUEUE(&i4b_rdqueue, m1); + _IF_DEQUEUE(&i4b_rdqueue, m1); i4b_Dfreembuf(m1); NDBGL4(L4_ERR, "ERROR, queue full, removing entry!"); } - IF_PREPEND(&i4b_rdqueue, m); + _IF_PREPEND(&i4b_rdqueue, m); + IF_UNLOCK(&i4b_rdqueue); splx(x); diff --git a/sys/net/bridge.c b/sys/net/bridge.c index 72747f2..00fce3a 100644 --- a/sys/net/bridge.c +++ b/sys/net/bridge.c @@ -830,23 +830,11 @@ forward: if (m == NULL) return ENOBUFS; bcopy(eh, mtod(m, struct ether_header *), ETHER_HDR_LEN); - s = splimp(); - if (IF_QFULL(&last->if_snd)) { - IF_DROP(&last->if_snd); + if (! IF_HANDOFF(&last->if_snd, m, last)) { #if 0 MUTE(last); /* should I also mute ? */ #endif - splx(s); - m_freem(m); /* consume the pkt anyways */ error = ENOBUFS ; - } else { - last->if_obytes += m->m_pkthdr.len ; - if (m->m_flags & M_MCAST) - last->if_omcasts++; - IF_ENQUEUE(&last->if_snd, m); - if ((last->if_flags & IFF_OACTIVE) == 0) - (*last->if_start)(last); - splx(s); } BDG_STAT(last, BDG_OUT); last = NULL ; @@ -857,7 +845,7 @@ forward: break ; if (ifp != src && /* do not send to self */ USED(ifp) && /* if used for bridging */ - ! IF_QFULL(&ifp->if_snd) && + ! _IF_QFULL(&ifp->if_snd) && (ifp->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING) && SAMECLUSTER(ifp, src) && !MUTED(ifp) ) diff --git a/sys/net/if.c b/sys/net/if.c index 1e5a4ef..cb77a31 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -110,12 +110,18 @@ ifinit(dummy) int s; s = splimp(); - for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) + for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { if (ifp->if_snd.ifq_maxlen == 0) { printf("%s%d XXX: driver didn't set ifq_maxlen\n", ifp->if_name, ifp->if_unit); ifp->if_snd.ifq_maxlen = ifqmaxlen; } + if (ifp->if_snd.ifq_mtx.mtx_description == NULL) { + printf("%s%d XXX: driver didn't initialize queue mtx\n", + ifp->if_name, ifp->if_unit); + mtx_init(&ifp->if_snd.ifq_mtx, "unknown", MTX_DEF); + } + } splx(s); if_slowtimo(0); } @@ -182,6 +188,8 @@ if_attach(ifp) ifindex2ifnet[if_index] = ifp; + mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_name, MTX_DEF); + /* * create a Link Level name for this device */ @@ -290,6 +298,7 @@ if_detach(ifp) #endif TAILQ_REMOVE(&ifnet, ifp, if_link); + mtx_destroy(&ifp->if_snd.ifq_mtx); splx(s); } diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c index 3c04db5..4d71d57 100644 --- a/sys/net/if_atmsubr.c +++ b/sys/net/if_atmsubr.c @@ -203,17 +203,8 @@ atm_output(ifp, m0, dst, rt0) * Queue message on interface, and start output if interface * not yet active. */ - s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - splx(s); - senderr(ENOBUFS); - } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); + if (! IF_HANDOFF(&ifp->if_snd, m, ifp)) + return (ENOBUFS); return (error); bad: @@ -301,13 +292,7 @@ atm_input(ifp, ah, m, rxhand) } } - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); - } else - IF_ENQUEUE(inq, m); - splx(s); + (void) IF_HANDOFF(inq, m, NULL); } /* diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index ad28d5d..f8e38ca 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -234,17 +234,11 @@ ef_start(struct ifnet *ifp) break; if (ifp->if_bpf) bpf_mtap(ifp, m); - if (IF_QFULL(&p->if_snd)) { - IF_DROP(&p->if_snd); + if (! IF_HANDOFF(&p->if_snd, m, NULL)) { ifp->if_oerrors++; - m_freem(m); continue; } - IF_ENQUEUE(&p->if_snd, m); - if ((p->if_flags & IFF_OACTIVE) == 0) { - p->if_start(p); - ifp->if_opackets++; - } + ifp->if_opackets++; } ifp->if_flags &= ~IFF_OACTIVE; return; @@ -419,13 +413,7 @@ ef_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m) ft, ether_type); return EPROTONOSUPPORT; } - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); - } else - IF_ENQUEUE(inq, m); - splx(s); + (void) IF_HANDOFF(inq, m, NULL); return 0; } diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 0bf8070..6d283a4 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -264,15 +264,9 @@ ether_output(ifp, m, dst, rt0) */ if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){ m->m_pkthdr.rcvif = ifp; - schednetisr(NETISR_NS); inq = &nsintrq; - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); - } else - IF_ENQUEUE(inq, m); - splx(s); + if (IF_HANDOFF(inq, m, NULL)) + schednetisr(NETISR_NS); return (error); } if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){ @@ -365,7 +359,7 @@ ether_output_frame(ifp, m) struct ifnet *ifp; struct mbuf *m; { - int s, error = 0; + int error = 0; #ifdef BRIDGE if (do_bridge) { @@ -382,24 +376,12 @@ ether_output_frame(ifp, m) } #endif - s = splimp(); /* - * Queue message on interface, and start output if interface - * not yet active. + * Queue message on interface, update output statistics if + * successful, and start output if interface not yet active. */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - splx(s); - m_freem(m); + if (! IF_HANDOFF(&ifp->if_snd, m, ifp)) return (ENOBUFS); - } - ifp->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); return (error); } @@ -641,13 +623,7 @@ ether_demux(ifp, eh, m) #endif /* NETATALK */ } - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); - } else - IF_ENQUEUE(inq, m); - splx(s); + (void) IF_HANDOFF(inq, m, NULL); } /* diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index f88a02b..186fec5 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -128,7 +128,7 @@ fddi_output(ifp, m, dst, rt0) struct rtentry *rt0; { u_int16_t type; - int s, loop_copy = 0, error = 0, hdrcmplt = 0; + int loop_copy = 0, error = 0, hdrcmplt = 0; u_char esrc[6], edst[6]; register struct rtentry *rt; register struct fddi_header *fh; @@ -350,23 +350,8 @@ fddi_output(ifp, m, dst, rt0) } } - s = splimp(); - /* - * Queue message on interface, and start output if interface - * not yet active. - */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - splx(s); + if (! IF_HANDOFF(&ifp->if_snd, m, ifp)) senderr(ENOBUFS); - } - ifp->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); return (error); bad: @@ -388,7 +373,6 @@ fddi_input(ifp, fh, m) { register struct ifqueue *inq; register struct llc *l; - int s; if ((ifp->if_flags & IFF_UP) == 0) { m_freem(m); @@ -520,13 +504,7 @@ fddi_input(ifp, fh, m) return; } - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); - } else - IF_ENQUEUE(inq, m); - splx(s); + (void) IF_HANDOFF(inq, m, NULL); } /* * Perform common duties while attaching to interface list diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 085ff3d..143f06f 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -314,7 +314,7 @@ gif_input(m, af, gifp) int af; struct ifnet *gifp; { - int s, isr; + int isr; register struct ifqueue *ifq = 0; if (gifp == NULL) { @@ -379,19 +379,11 @@ gif_input(m, af, gifp) return; } - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); /* update statistics */ - m_freem(m); - splx(s); - return; - } - IF_ENQUEUE(ifq, m); - /* we need schednetisr since the address family may change */ - schednetisr(isr); gifp->if_ipackets++; gifp->if_ibytes += m->m_pkthdr.len; - splx(s); + (void) IF_HANDOFF(ifq, m, NULL); + /* we need schednetisr since the address family may change */ + schednetisr(isr); return; } diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c index 4141ffd..5b7fd22 100644 --- a/sys/net/if_iso88025subr.c +++ b/sys/net/if_iso88025subr.c @@ -162,10 +162,10 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct register struct iso88025_sockaddr_data *sd = (struct iso88025_sockaddr_data *)dst->sa_data; register struct llc *l; register struct sockaddr_dl *sdl = NULL; - int s, error = 0, rif_len = 0; + int error = 0, rif_len = 0; u_char edst[6]; register struct rtentry *rt; - int len = m->m_pkthdr.len, loop_copy = 0; + int loop_copy = 0; struct arpcom *ac = (struct arpcom *)ifp; if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) @@ -294,24 +294,10 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct } } - s = splimp(); - /* - * Queue message on interface, and start output if interface - * not yet active. - */ - if (IF_QFULL(&ifp->if_snd)) { - printf("iso88025_output: packet dropped QFULL.\n"); - IF_DROP(&ifp->if_snd); - splx(s); + if (! IF_HANDOFF_ADJ(&ifp->if_snd, m, ifp, ISO88025_HDR_LEN + 8)) { + printf("iso88025_output: packet dropped QFULL.\n"); senderr(ENOBUFS); } - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); - ifp->if_obytes += len + ISO88025_HDR_LEN + 8; return (error); bad: @@ -328,7 +314,6 @@ iso88025_input(struct ifnet *ifp, struct iso88025_header *th, struct mbuf *m) { register struct ifqueue *inq; u_short ether_type; - int s; register struct llc *l = mtod(m, struct llc *); if ((ifp->if_flags & IFF_UP) == 0) { @@ -413,12 +398,6 @@ iso88025_input(struct ifnet *ifp, struct iso88025_header *th, struct mbuf *m) return; } - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - m_freem(m); + if (! IF_HANDOFF(inq, m, NULL)) printf("iso88025_input: Packet dropped (Queue full).\n"); - } else - IF_ENQUEUE(inq, m); - splx(s); } diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 21f9695..a76466b 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -207,8 +207,8 @@ if_simloop(ifp, m, af, hlen) int af; int hlen; { - int s, isr; - register struct ifqueue *ifq = 0; + int isr; + struct ifqueue *inq = 0; KASSERT((m->m_flags & M_PKTHDR) != 0, ("if_simloop: no HDR")); m->m_pkthdr.rcvif = ifp; @@ -261,32 +261,32 @@ if_simloop(ifp, m, af, hlen) switch (af) { #ifdef INET case AF_INET: - ifq = &ipintrq; + inq = &ipintrq; isr = NETISR_IP; break; #endif #ifdef INET6 case AF_INET6: m->m_flags |= M_LOOP; - ifq = &ip6intrq; + inq = &ip6intrq; isr = NETISR_IPV6; break; #endif #ifdef IPX case AF_IPX: - ifq = &ipxintrq; + inq = &ipxintrq; isr = NETISR_IPX; break; #endif #ifdef NS case AF_NS: - ifq = &nsintrq; + inq = &nsintrq; isr = NETISR_NS; break; #endif #ifdef NETATALK case AF_APPLETALK: - ifq = &atintrq2; + inq = &atintrq2; isr = NETISR_ATALK; break; #endif NETATALK @@ -295,18 +295,10 @@ if_simloop(ifp, m, af, hlen) m_freem(m); return (EAFNOSUPPORT); } - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - splx(s); - return (ENOBUFS); - } - IF_ENQUEUE(ifq, m); - schednetisr(isr); ifp->if_ipackets++; ifp->if_ibytes += m->m_pkthdr.len; - splx(s); + (void) IF_HANDOFF(inq, m, NULL); + schednetisr(isr); return (0); } diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 9abb893..c5eb10c 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -211,6 +211,9 @@ pppattach(dummy) sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&sc->sc_inq.ifq_mtx, "ppp_inq", MTX_DEF); + mtx_init(&sc->sc_fastq.ifq_mtx, "ppp_fastq", MTX_DEF); + mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", MTX_DEF); if_attach(&sc->sc_if); bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); } @@ -280,24 +283,9 @@ pppdealloc(sc) getmicrotime(&sc->sc_if.if_lastchange); sc->sc_devp = NULL; sc->sc_xfer = 0; - for (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - m_freem(m); - } - for (;;) { - IF_DEQUEUE(&sc->sc_inq, m); - if (m == NULL) - break; - m_freem(m); - } - for (;;) { - IF_DEQUEUE(&sc->sc_fastq, m); - if (m == NULL) - break; - m_freem(m); - } + IF_DRAIN(&sc->sc_rawq); + IF_DRAIN(&sc->sc_inq); + IF_DRAIN(&sc->sc_fastq); while ((m = sc->sc_npqueue) != NULL) { sc->sc_npqueue = m->m_nextpkt; m_freem(m); @@ -338,7 +326,8 @@ pppioctl(sc, cmd, data, flag, p) int flag; struct proc *p; { - int s, error, flags, mru, nb, npx; + int s, flags, mru, nb, npx; + int error = 0; struct ppp_option_data *odp; struct compressor **cp; struct npioctl *npi; @@ -367,7 +356,7 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCSFLAGS: if ((error = suser(p)) != 0) - return (error); + break; flags = *(int *)data & SC_MASK; s = splsoftnet(); #ifdef PPP_COMPRESS @@ -394,7 +383,7 @@ pppioctl(sc, cmd, data, flag, p) #ifdef VJC case PPPIOCSMAXCID: if ((error = suser(p)) != 0) - return (error); + break; if (sc->sc_comp) { s = splsoftnet(); sl_compress_init(sc->sc_comp, *(int *)data); @@ -405,22 +394,24 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCXFERUNIT: if ((error = suser(p)) != 0) - return (error); + break; sc->sc_xfer = p->p_pid; break; #ifdef PPP_COMPRESS case PPPIOCSCOMPRESS: if ((error = suser(p)) != 0) - return (error); + break; odp = (struct ppp_option_data *) data; nb = odp->length; if (nb > sizeof(ccp_option)) nb = sizeof(ccp_option); if ((error = copyin(odp->ptr, ccp_option, nb)) != 0) - return (error); - if (ccp_option[1] < 2) /* preliminary check on the length byte */ - return (EINVAL); + break; + if (ccp_option[1] < 2) { /* preliminary check on the length byte */ + error = EINVAL; + break; + } for (cp = ppp_compressors; *cp != NULL; ++cp) if ((*cp)->compress_proto == ccp_option[0]) { /* @@ -459,13 +450,14 @@ pppioctl(sc, cmd, data, flag, p) sc->sc_flags &= ~SC_DECOMP_RUN; splx(s); } - return (error); + break; } if (sc->sc_flags & SC_DEBUG) printf("ppp%d: no compressor for [%x %x %x], %x\n", sc->sc_if.if_unit, ccp_option[0], ccp_option[1], ccp_option[2], nb); - return (EINVAL); /* no handler found */ + error = EINVAL; /* no handler found */ + break; #endif /* PPP_COMPRESS */ case PPPIOCGNPMODE: @@ -476,13 +468,15 @@ pppioctl(sc, cmd, data, flag, p) npx = NP_IP; break; default: - return EINVAL; + error = EINVAL; } + if (error) + break; if (cmd == PPPIOCGNPMODE) { npi->mode = sc->sc_npmode[npx]; } else { if ((error = suser(p)) != 0) - return (error); + break; if (npi->mode != sc->sc_npmode[npx]) { s = splsoftnet(); sc->sc_npmode[npx] = npi->mode; @@ -507,22 +501,26 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCSPASS: case PPPIOCSACTIVE: nbp = (struct bpf_program *) data; - if ((unsigned) nbp->bf_len > BPF_MAXINSNS) - return EINVAL; + if ((unsigned) nbp->bf_len > BPF_MAXINSNS) { + error = EINVAL; + break; + } newcodelen = nbp->bf_len * sizeof(struct bpf_insn); if (newcodelen != 0) { MALLOC(newcode, struct bpf_insn *, newcodelen, M_DEVBUF, M_WAITOK); if (newcode == 0) { - return EINVAL; /* or sumpin */ + error = EINVAL; /* or sumpin */ + break; } if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode, newcodelen)) != 0) { FREE(newcode, M_DEVBUF); - return error; + break; } if (!bpf_validate(newcode, nbp->bf_len)) { FREE(newcode, M_DEVBUF); - return EINVAL; + error = EINVAL; + break; } } else newcode = 0; @@ -538,9 +536,10 @@ pppioctl(sc, cmd, data, flag, p) #endif default: - return (ENOIOCTL); + error = ENOIOCTL; + break; } - return (0); + return (error); } /* @@ -835,15 +834,17 @@ pppoutput(ifp, m0, dst, rtp) } else { /* fastq and if_snd are emptied at spl[soft]net now */ ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd; - if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { - IF_DROP(ifq); - splx(s); + IF_LOCK(ifq); + if (_IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { + _IF_DROP(ifq); + IF_UNLOCK(ifq); sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; error = ENOBUFS; goto bad; } - IF_ENQUEUE(ifq, m0); + _IF_ENQUEUE(ifq, m0); + IF_UNLOCK(ifq); (*sc->sc_start)(sc); } getmicrotime(&ifp->if_lastchange); @@ -888,12 +889,10 @@ ppp_requeue(sc) *mpp = m->m_nextpkt; m->m_nextpkt = NULL; ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if (! IF_HANDOFF(ifq, m, NULL)) { sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - } else - IF_ENQUEUE(ifq, m); + } break; case NPMODE_DROP: @@ -1511,17 +1510,12 @@ ppp_inproc(sc, m) /* * Put the packet on the appropriate input queue. */ - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - splx(s); + if (! IF_HANDOFF(inq, m, NULL)) { if (sc->sc_flags & SC_DEBUG) printf("ppp%d: input queue full\n", ifp->if_unit); ifp->if_iqdrops++; goto bad; } - IF_ENQUEUE(inq, m); - splx(s); ifp->if_ipackets++; ifp->if_ibytes += ilen; getmicrotime(&ifp->if_lastchange); @@ -1532,7 +1526,8 @@ ppp_inproc(sc, m) return; bad: - m_freem(m); + if (m) + m_freem(m); sc->sc_if.if_ierrors++; sc->sc_stats.ppp_ierrors++; } diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 45483bb..50888ee 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -291,6 +291,7 @@ slcreate() sc->sc_fastq.ifq_maxlen = 32; sc->sc_if.if_linkmib = sc; sc->sc_if.if_linkmiblen = sizeof *sc; + mtx_init(&sc->sc_fastq.ifq_mtx, "sl_fastq", MTX_DEF); /* * Find a suitable unit number. @@ -372,6 +373,7 @@ sldestroy(struct sl_softc *sc) { if_detach(&sc->sc_if); LIST_REMOVE(sc, sl_next); m_free(sc->sc_mbuf); + mtx_destroy(&sc->sc_fastq.ifq_mtx); FREE(sc, M_SL); } @@ -560,15 +562,11 @@ sloutput(ifp, m, dst, rtp) } if (ip->ip_tos & IPTOS_LOWDELAY) ifq = &sc->sc_fastq; - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - splx(s); + if (! IF_HANDOFF(ifq, m, NULL)) { sc->sc_if.if_oerrors++; return (ENOBUFS); } - IF_ENQUEUE(ifq, m); + s = splimp(); if (sc->sc_ttyp->t_outq.c_cc == 0) slstart(sc->sc_ttyp); splx(s); @@ -824,7 +822,6 @@ slinput(c, tp) register struct sl_softc *sc; register struct mbuf *m; register int len; - int s; u_char chdr[CHDR_LEN]; tk_nin++; @@ -955,17 +952,12 @@ slinput(c, tp) goto newpack; } - s = splimp(); - if (IF_QFULL(&ipintrq)) { - IF_DROP(&ipintrq); + if (! IF_HANDOFF(&ipintrq, m, NULL)) { sc->sc_if.if_ierrors++; sc->sc_if.if_iqdrops++; - m_freem(m); } else { - IF_ENQUEUE(&ipintrq, m); schednetisr(NETISR_IP); } - splx(s); goto newpack; } if (sc->sc_mp < sc->sc_ep) { diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index eec4fc1..052274a 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -590,18 +590,12 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) goto drop; /* Check queue. */ - s = splimp(); - if (IF_QFULL (inq)) { - /* Queue overflow. */ - IF_DROP(inq); - splx(s); + if (! IF_HANDOFF(inq, m, NULL)) { if (debug) log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", SPP_ARGS(ifp)); goto drop; } - IF_ENQUEUE(inq, m); - splx(s); } /* @@ -669,7 +663,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, * Put low delay, telnet, rlogin and ftp control packets * in front of the queue. */ - if (IF_QFULL (&sp->pp_fastq)) + if (_IF_QFULL(&sp->pp_fastq)) ; else if (ip->ip_tos & IPTOS_LOWDELAY) ifq = &sp->pp_fastq; @@ -761,26 +755,14 @@ nosupport: /* * Queue message on interface, and start output if interface - * not yet active. + * not yet active. Also adjust output byte count. + * The packet length includes header, FCS and 1 flag, + * according to RFC 1333. */ - if (IF_QFULL (ifq)) { - IF_DROP (&ifp->if_snd); - m_freem (m); + if (! IF_HANDOFF_ADJ(ifq, m, ifp, 3)) { ++ifp->if_oerrors; - splx (s); return (rv? rv: ENOBUFS); } - IF_ENQUEUE (ifq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - - /* - * Count output packets and bytes. - * The packet length includes header, FCS and 1 flag, - * according to RFC 1333. - */ - ifp->if_obytes += m->m_pkthdr.len + 3; - splx (s); return (0); } @@ -813,6 +795,8 @@ sppp_attach(struct ifnet *ifp) sp->pp_phase = PHASE_DEAD; sp->pp_up = lcp.Up; sp->pp_down = lcp.Down; + mtx_init(&sp->pp_cpq.ifq_mtx, "sppp_cpq", MTX_DEF); + mtx_init(&sp->pp_fastq.ifq_mtx, "sppp_fastq", MTX_DEF); sppp_lcp_init(sp); sppp_ipcp_init(sp); @@ -840,6 +824,8 @@ sppp_detach(struct ifnet *ifp) for (i = 0; i < IDX_COUNT; i++) UNTIMEOUT((cps[i])->TO, (void *)sp, sp->ch[i]); UNTIMEOUT(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch); + mtx_destroy(&sp->pp_cpq.ifq_mtx); + mtx_destroy(&sp->pp_fastq.ifq_mtx); } /* @@ -1161,15 +1147,8 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2) SPP_ARGS(ifp), (u_long)ntohl (ch->type), (u_long)ch->par1, (u_long)ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1); - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; + if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) + ifp->if_oerrors++; } /* @@ -1217,16 +1196,8 @@ sppp_cp_send(struct sppp *sp, u_short proto, u_char type, sppp_print_bytes ((u_char*) (lh+1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); - ++ifp->if_oerrors; - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; + if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) + ifp->if_oerrors++; } /* @@ -3727,16 +3698,8 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, sppp_print_bytes((u_char*) (lh+1), len); addlog(">\n"); } - if (IF_QFULL (&sp->pp_cpq)) { - IF_DROP (&sp->pp_fastq); - IF_DROP (&ifp->if_snd); - m_freem (m); - ++ifp->if_oerrors; - } else - IF_ENQUEUE (&sp->pp_cpq, m); - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - ifp->if_obytes += m->m_pkthdr.len + 3; + if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) + ifp->if_oerrors++; } /* diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 6b3834d..8ae33de 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -484,7 +484,7 @@ in_stf_input(m, va_alist) struct ip *ip; struct ip6_hdr *ip6; u_int8_t otos, itos; - int s, isr; + int len, isr; struct ifqueue *ifq = NULL; struct ifnet *ifp; va_list ap; @@ -581,18 +581,12 @@ in_stf_input(m, va_alist) ifq = &ip6intrq; isr = NETISR_IPV6; - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); /* update statistics */ - m_freem(m); - splx(s); + len = m->m_pkthdr.len; + if (! IF_HANDOFF(ifq, m, NULL)) return; - } - IF_ENQUEUE(ifq, m); schednetisr(isr); ifp->if_ipackets++; - ifp->if_ibytes += m->m_pkthdr.len; - splx(s); + ifp->if_ibytes += len; } /* ARGSUSED */ diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 9187764..5cbe111 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -196,7 +196,6 @@ tunclose(dev, foo, bar, p) register int s; struct tun_softc *tp; struct ifnet *ifp; - struct mbuf *m; tp = dev->si_drv1; ifp = &tp->tun_if; @@ -207,13 +206,7 @@ tunclose(dev, foo, bar, p) /* * junk all pending output */ - do { - s = splimp(); - IF_DEQUEUE(&ifp->if_snd, m); - splx(s); - if (m) - m_freem(m); - } while (m); + IF_DRAIN(&ifp->if_snd); if (ifp->if_flags & IFF_UP) { s = splimp(); @@ -337,7 +330,6 @@ tunoutput(ifp, m0, dst, rt) struct rtentry *rt; { struct tun_softc *tp = ifp->if_softc; - int s; TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); @@ -380,10 +372,8 @@ tunoutput(ifp, m0, dst, rt) M_PREPEND(m0, dst->sa_len, M_DONTWAIT); /* if allocation failed drop packet */ - if (m0 == NULL){ - s = splimp(); /* spl on queue manipulation */ - IF_DROP(&ifp->if_snd); - splx(s); + if (m0 == NULL) { + ifp->if_iqdrops++; ifp->if_oerrors++; return (ENOBUFS); } else { @@ -396,10 +386,8 @@ tunoutput(ifp, m0, dst, rt) M_PREPEND(m0, 4, M_DONTWAIT); /* if allocation failed drop packet */ - if (m0 == NULL){ - s = splimp(); /* spl on queue manipulation */ - IF_DROP(&ifp->if_snd); - splx(s); + if (m0 == NULL) { + ifp->if_iqdrops++; ifp->if_oerrors++; return ENOBUFS; } else @@ -414,17 +402,10 @@ tunoutput(ifp, m0, dst, rt) } } - s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - m_freem(m0); - splx(s); + if (! IF_HANDOFF(&ifp->if_snd, m0, NULL)) { ifp->if_collisions++; return ENOBUFS; } - ifp->if_obytes += m0->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m0); - splx(s); ifp->if_opackets++; if (tp->tun_flags & TUN_RWAIT) { diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 2455d69..43e580f 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -75,6 +75,9 @@ struct ether_header; #include /* get TAILQ macros */ +#include +#include + TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ TAILQ_HEAD(ifprefixhead, ifprefix); @@ -89,6 +92,7 @@ struct ifqueue { int ifq_len; int ifq_maxlen; int ifq_drops; + struct mtx ifq_mtx; }; /* @@ -107,6 +111,7 @@ struct ifnet { short if_unit; /* sub-unit for lower level driver */ short if_timer; /* time 'til if_watchdog called */ short if_flags; /* up/down, broadcast, etc. */ + int if_mpsafe; /* XXX TEMPORARY */ int if_ipending; /* interrupts pending */ void *if_linkmib; /* link-type-specific MIB data */ size_t if_linkmiblen; /* length of above data */ @@ -141,6 +146,7 @@ struct ifnet { struct ifqueue *if_poll_slowq; /* input queue for slow devices */ struct ifprefixhead if_prefixhead; /* list of prefixes per if */ }; + typedef void if_init_f_t __P((void *)); #define if_mtu if_data.ifi_mtu @@ -183,61 +189,105 @@ typedef void if_init_f_t __P((void *)); * (defined above). Entries are added to and deleted from these structures * by these macros, which should be called with ipl raised to splimp(). */ -#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) -#define IF_DROP(ifq) ((ifq)->ifq_drops++) -#define IF_ENQUEUE(ifq, m) { \ - (m)->m_nextpkt = 0; \ - if ((ifq)->ifq_tail == 0) \ - (ifq)->ifq_head = m; \ - else \ - (ifq)->ifq_tail->m_nextpkt = m; \ - (ifq)->ifq_tail = m; \ - (ifq)->ifq_len++; \ -} -#define IF_PREPEND(ifq, m) { \ - (m)->m_nextpkt = (ifq)->ifq_head; \ - if ((ifq)->ifq_tail == 0) \ - (ifq)->ifq_tail = (m); \ - (ifq)->ifq_head = (m); \ - (ifq)->ifq_len++; \ -} -#define IF_DEQUEUE(ifq, m) { \ - (m) = (ifq)->ifq_head; \ - if (m) { \ - if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \ - (ifq)->ifq_tail = 0; \ - (m)->m_nextpkt = 0; \ - (ifq)->ifq_len--; \ - } \ -} +#define IF_LOCK(ifq) mtx_enter(&(ifq)->ifq_mtx, MTX_DEF) +#define IF_UNLOCK(ifq) mtx_exit(&(ifq)->ifq_mtx, MTX_DEF) +#define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) +#define _IF_DROP(ifq) ((ifq)->ifq_drops++) +#define _IF_QLEN(ifq) ((ifq)->ifq_len) + +#define _IF_ENQUEUE(ifq, m) do { \ + (m)->m_nextpkt = NULL; \ + if ((ifq)->ifq_tail == NULL) \ + (ifq)->ifq_head = m; \ + else \ + (ifq)->ifq_tail->m_nextpkt = m; \ + (ifq)->ifq_tail = m; \ + (ifq)->ifq_len++; \ +} while (0) + +#define IF_ENQUEUE(ifq, m) do { \ + IF_LOCK(ifq); \ + _IF_ENQUEUE(ifq, m); \ + IF_UNLOCK(ifq); \ +} while (0) + +#define _IF_PREPEND(ifq, m) do { \ + (m)->m_nextpkt = (ifq)->ifq_head; \ + if ((ifq)->ifq_tail == NULL) \ + (ifq)->ifq_tail = (m); \ + (ifq)->ifq_head = (m); \ + (ifq)->ifq_len++; \ +} while (0) + +#define IF_PREPEND(ifq, m) do { \ + IF_LOCK(ifq); \ + _IF_PREPEND(ifq, m); \ + IF_UNLOCK(ifq); \ +} while (0) + +#define _IF_DEQUEUE(ifq, m) do { \ + (m) = (ifq)->ifq_head; \ + if (m) { \ + if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \ + (ifq)->ifq_tail = NULL; \ + (m)->m_nextpkt = NULL; \ + (ifq)->ifq_len--; \ + } \ +} while (0) + +#define IF_DEQUEUE(ifq, m) do { \ + IF_LOCK(ifq); \ + _IF_DEQUEUE(ifq, m); \ + IF_UNLOCK(ifq); \ +} while (0) + +#define IF_DRAIN(ifq) do { \ + struct mbuf *m; \ + IF_LOCK(ifq); \ + for (;;) { \ + _IF_DEQUEUE(ifq, m); \ + if (m == NULL) \ + break; \ + m_freem(m); \ + } \ + IF_UNLOCK(ifq); \ +} while (0) #ifdef _KERNEL -#define IF_ENQ_DROP(ifq, m) if_enq_drop(ifq, m) - -#if defined(__GNUC__) && defined(MT_HEADER) -static __inline int -if_queue_drop(struct ifqueue *ifq, struct mbuf *m) -{ - IF_DROP(ifq); - return 0; -} +#define IF_HANDOFF(ifq, m, ifp) if_handoff(ifq, m, ifp, 0) +#define IF_HANDOFF_ADJ(ifq, m, ifp, adj) if_handoff(ifq, m, ifp, adj) static __inline int -if_enq_drop(struct ifqueue *ifq, struct mbuf *m) +if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) { - if (IF_QFULL(ifq) && - !if_queue_drop(ifq, m)) - return 0; - IF_ENQUEUE(ifq, m); - return 1; + int active = 0; + + IF_LOCK(ifq); + if (_IF_QFULL(ifq)) { + _IF_DROP(ifq); + IF_UNLOCK(ifq); + m_freem(m); + return (0); + } + if (ifp != NULL) { + ifp->if_obytes += m->m_pkthdr.len + adjust; + if (m->m_flags & M_MCAST) + ifp->if_omcasts++; + active = ifp->if_flags & IFF_OACTIVE; + } + _IF_ENQUEUE(ifq, m); + IF_UNLOCK(ifq); + if (ifp != NULL && !active) { + if (ifp->if_mpsafe) { + DROP_GIANT_NOSWITCH(); + (*ifp->if_start)(ifp); + PICKUP_GIANT(); + } else { + (*ifp->if_start)(ifp); + } + } + return (1); } -#else - -#ifdef MT_HEADER -int if_enq_drop __P((struct ifqueue *, struct mbuf *)); -#endif - -#endif /* * 72 was chosen below because it is the size of a TCP/IP @@ -371,5 +421,4 @@ int if_simloop __P((struct ifnet *ifp, struct mbuf *m, int af, int hlen)); #endif /* _KERNEL */ - #endif /* !_NET_IF_VAR_H_ */ diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 5c4292c..d20dbcc 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -261,18 +261,10 @@ vlan_start(struct ifnet *ifp) * Send it, precisely as ether_output() would have. * We are already running at splimp. */ - if (IF_QFULL(&p->if_snd)) { - IF_DROP(&p->if_snd); - /* XXX stats */ - ifp->if_oerrors++; - m_freem(m); - continue; - } - IF_ENQUEUE(&p->if_snd, m); - if ((p->if_flags & IFF_OACTIVE) == 0) { - p->if_start(p); + if (IF_HANDOFF(&p->if_snd, m, p)) ifp->if_opackets++; - } + else + ifp->if_oerrors++; } ifp->if_flags &= ~IFF_OACTIVE; diff --git a/sys/net/intrq.c b/sys/net/intrq.c index 5739385..d05176c 100644 --- a/sys/net/intrq.c +++ b/sys/net/intrq.c @@ -82,20 +82,13 @@ family_enqueue(family, m) sa_family_t family; struct mbuf *m; { - int entry, s; + int entry; for (entry = 0; entry < sizeof queue / sizeof queue[0]; entry++) if (queue[entry].family == family) { if (queue[entry].present) { - s = splimp(); - if (IF_QFULL(queue[entry].q)) { - IF_DROP(queue[entry].q); - splx(s); - m_freem(m); + if (! IF_HANDOFF(queue[entry].q, m, NULL)) return ENOBUFS; - } - IF_ENQUEUE(queue[entry].q, m); - splx(s); schednetisr(queue[entry].isr); return 0; } else diff --git a/sys/netatalk/ddp_pcb.c b/sys/netatalk/ddp_pcb.c index 167c0b3..617ab29 100644 --- a/sys/netatalk/ddp_pcb.c +++ b/sys/netatalk/ddp_pcb.c @@ -548,6 +548,8 @@ ddp_init(void ) { atintrq1.ifq_maxlen = IFQ_MAXLEN; atintrq2.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&atintrq1.ifq_mtx, "at1_inq", MTX_DEF); + mtx_init(&atintrq2.ifq_mtx, "at2_inq", MTX_DEF); } #if 0 diff --git a/sys/netatalk/ddp_usrreq.c b/sys/netatalk/ddp_usrreq.c index 167c0b3..617ab29 100644 --- a/sys/netatalk/ddp_usrreq.c +++ b/sys/netatalk/ddp_usrreq.c @@ -548,6 +548,8 @@ ddp_init(void ) { atintrq1.ifq_maxlen = IFQ_MAXLEN; atintrq2.ifq_maxlen = IFQ_MAXLEN; + mtx_init(&atintrq1.ifq_mtx, "at1_inq", MTX_DEF); + mtx_init(&atintrq2.ifq_mtx, "at2_inq", MTX_DEF); } #if 0 diff --git a/sys/netatm/atm_device.c b/sys/netatm/atm_device.c index e458bf4..ecca8ad 100644 --- a/sys/netatm/atm_device.c +++ b/sys/netatm/atm_device.c @@ -314,6 +314,7 @@ atm_dev_lower(cmd, tok, arg1, arg2) * Free any buffers from this VCC on the ATM interrupt queue */ prev = NULL; + IF_LOCK(&atm_intrq); for (m = atm_intrq.ifq_head; m; m = next) { next = KB_QNEXT(m); @@ -344,6 +345,7 @@ atm_dev_lower(cmd, tok, arg1, arg2) prev = m; } } + IF_UNLOCK(&atm_intrq); (void) splx(s); /* diff --git a/sys/netatm/atm_subr.c b/sys/netatm/atm_subr.c index e1478df..25003e6 100644 --- a/sys/netatm/atm_subr.c +++ b/sys/netatm/atm_subr.c @@ -135,6 +135,7 @@ atm_initialize() atm_intrq.ifq_maxlen = ATM_INTRQ_MAX; + mtx_init(&atm_intrq.ifq_mtx, "atm_inq", MTX_DEF); #ifdef sgi atm_intr_index = register_isr(atm_intr); #endif diff --git a/sys/netatm/ipatm/ipatm_input.c b/sys/netatm/ipatm/ipatm_input.c index 8480506..30f6326 100644 --- a/sys/netatm/ipatm/ipatm_input.c +++ b/sys/netatm/ipatm/ipatm_input.c @@ -127,7 +127,6 @@ ipatm_ipinput(inp, m) struct ip_nif *inp; KBuffer *m; { - int s; #if BSD < 199103 int space; #endif @@ -207,16 +206,8 @@ ipatm_ipinput(inp, m) * just call IP directly to avoid the extra unnecessary * kernel scheduling. */ - s = splimp(); - if (IF_QFULL(&ipintrq)) { - IF_DROP(&ipintrq); - (void) splx(s); - KB_FREEALL(m); + if (! IF_HANDOFF(&ipintrq, m, NULL)) return (1); - } - - IF_ENQUEUE(&ipintrq, m); - (void) splx(s); #if BSD < 199506 ipintr(); #else diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 97dc239..1bbe164 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -96,7 +96,7 @@ struct llinfo_arp { static LIST_HEAD(, llinfo_arp) llinfo_arp; -struct ifqueue arpintrq = {0, 0, 0, 50}; +struct ifqueue arpintrq; static int arp_inuse, arp_allocated; static int arp_maxtries = 5; @@ -110,6 +110,7 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW, SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, &arp_proxyall, 0, ""); +static void arp_init __P((void)); static void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *)); static void arprequest __P((struct arpcom *, struct in_addr *, struct in_addr *, u_char *)); @@ -815,3 +816,13 @@ arp_ifinit(ac, ifa) ifa->ifa_rtrequest = arp_rtrequest; ifa->ifa_flags |= RTF_CLONING; } + +static void +arp_init(void) +{ + + arpintrq.ifq_maxlen = 50; + mtx_init(&arpintrq.ifq_mtx, "arp_inq", MTX_DEF); +} + +SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0); diff --git a/sys/netinet/ip_auth.c b/sys/netinet/ip_auth.c index 4ce6a69..7fb9d21 100644 --- a/sys/netinet/ip_auth.c +++ b/sys/netinet/ip_auth.c @@ -286,9 +286,6 @@ int cmd; frentry_t *fr, **frptr; { mb_t *m; -#if defined(_KERNEL) && !SOLARIS - struct ifqueue *ifq; -#endif frauth_t auth, *au = &auth; frauthent_t *fae, **faep; int i, error = 0; @@ -423,15 +420,10 @@ fr_authioctlloop: # if SOLARIS error = fr_qin(fr_auth[i].fra_q, m); # else /* SOLARIS */ - ifq = &ipintrq; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if (! IF_HANDOFF(&ipintrq, m, NULL)) error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m); + else schednetisr(NETISR_IP); - } # endif /* SOLARIS */ if (error) fr_authstats.fas_quefail++; diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index beb620b..63e10c8 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -235,6 +235,7 @@ ip_init() ip_id = time_second & 0xffff; ipintrq.ifq_maxlen = ipqmaxlen; + mtx_init(&ipintrq.ifq_mtx, "ip_inq", MTX_DEF); register_netisr(NETISR_IP, ipintr); } @@ -745,13 +746,10 @@ bad: static void ipintr(void) { - int s; struct mbuf *m; - while(1) { - s = splimp(); + while (1) { IF_DEQUEUE(&ipintrq, m); - splx(s); if (m == 0) return; ip_input(m); diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index d1122b1..fb7a2b8 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -1622,8 +1622,6 @@ ipip_input(m, off, proto) struct ifnet *ifp = m->m_pkthdr.rcvif; register struct ip *ip = mtod(m, struct ip *); register int hlen = ip->ip_hl << 2; - register int s; - register struct ifqueue *ifq; register struct vif *vifp; if (!have_encap_tunnel) { @@ -1675,13 +1673,7 @@ ipip_input(m, off, proto) m->m_pkthdr.len -= IP_HDR_LEN; m->m_pkthdr.rcvif = ifp; - ifq = &ipintrq; - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - } else { - IF_ENQUEUE(ifq, m); + (void) IF_HANDOFF(&ipintrq, m, NULL); /* * normally we would need a "schednetisr(NETISR_IP)" * here but we were called by ip_input and it is going @@ -1689,8 +1681,6 @@ ipip_input(m, off, proto) * queued as soon as we return so we avoid the * unnecessary software interrrupt. */ - } - splx(s); } /* diff --git a/sys/netinet6/ah_input.c b/sys/netinet6/ah_input.c index 1aaa0c4..b0489d1 100644 --- a/sys/netinet6/ah_input.c +++ b/sys/netinet6/ah_input.c @@ -470,16 +470,13 @@ ah4_input(m, va_alist) key_sa_recordxfer(sav, m); - s = splimp(); - if (IF_QFULL(&ipintrq)) { + if (! IF_HANDOFF(&ipintrq, m, NULL)) { ipsecstat.in_inval++; - splx(s); + m = NULL; goto fail; } - IF_ENQUEUE(&ipintrq, m); m = NULL; schednetisr(NETISR_IP); /*can be skipped but to make sure*/ - splx(s); nxt = IPPROTO_DONE; } else { /* @@ -596,7 +593,6 @@ ah6_input(mp, offp, proto) u_char *cksum; struct secasvar *sav = NULL; u_int16_t nxt; - int s; #ifndef PULLDOWN_TEST IP6_EXTHDR_CHECK(m, off, sizeof(struct ah), IPPROTO_DONE); @@ -875,16 +871,13 @@ ah6_input(mp, offp, proto) key_sa_recordxfer(sav, m); - s = splimp(); - if (IF_QFULL(&ip6intrq)) { + if (! IF_HANDOFF(&ip6intrq, m, NULL)) { ipsec6stat.in_inval++; - splx(s); + m = NULL; goto fail; } - IF_ENQUEUE(&ip6intrq, m); m = NULL; schednetisr(NETISR_IPV6); /*can be skipped but to make sure*/ - splx(s); nxt = IPPROTO_DONE; } else { /* diff --git a/sys/netinet6/esp_input.c b/sys/netinet6/esp_input.c index 0916276..4d4344b 100644 --- a/sys/netinet6/esp_input.c +++ b/sys/netinet6/esp_input.c @@ -122,7 +122,6 @@ esp4_input(m, va_alist) int ivlen; size_t hlen; size_t esplen; - int s; va_list ap; int off, proto; @@ -389,16 +388,13 @@ noreplaycheck: key_sa_recordxfer(sav, m); - s = splimp(); - if (IF_QFULL(&ipintrq)) { + if (! IF_HANDOFF(&ipintrq, m, NULL)) { ipsecstat.in_inval++; - splx(s); + m = NULL; goto bad; } - IF_ENQUEUE(&ipintrq, m); m = NULL; schednetisr(NETISR_IP); /*can be skipped but to make sure*/ - splx(s); nxt = IPPROTO_DONE; } else { /* @@ -733,16 +729,13 @@ noreplaycheck: key_sa_recordxfer(sav, m); - s = splimp(); - if (IF_QFULL(&ip6intrq)) { + if (! IF_HANDOFF(&ip6intrq, m, NULL)) { ipsec6stat.in_inval++; - splx(s); + m = NULL; goto bad; } - IF_ENQUEUE(&ip6intrq, m); m = NULL; schednetisr(NETISR_IPV6); /*can be skipped but to make sure*/ - splx(s); nxt = IPPROTO_DONE; } else { /* diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 6ded430..6238179 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -167,6 +167,7 @@ ip6_init() pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) ip6_protox[pr->pr_protocol] = pr - inet6sw; ip6intrq.ifq_maxlen = ip6qmaxlen; + mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", MTX_DEF); register_netisr(NETISR_IPV6, ip6intr); nd6_init(); frag6_init(); diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c index e16285c..dc4a1a3 100644 --- a/sys/netipx/ipx_input.c +++ b/sys/netipx/ipx_input.c @@ -107,6 +107,7 @@ ipx_init() read_random(&ipx_pexseq, sizeof ipx_pexseq); ipxintrq.ifq_maxlen = ipxqmaxlen; + mtx_init(&ipxintrq.ifq_mtx, "ipx_inq", MTX_DEF); ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb; ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb; diff --git a/sys/netipx/ipx_ip.c b/sys/netipx/ipx_ip.c index 7abd9da..9062d3b 100644 --- a/sys/netipx/ipx_ip.c +++ b/sys/netipx/ipx_ip.c @@ -225,16 +225,8 @@ ipxip_input(m, hlen) /* * Deliver to IPX */ - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - splx(s); - return; - } - IF_ENQUEUE(ifq, m); - schednetisr(NETISR_IPX); - splx(s); + if (IF_HANDOFF(ifq, m, NULL)) + schednetisr(NETISR_IPX); return; } diff --git a/sys/netnatm/natm_proto.c b/sys/netnatm/natm_proto.c index 2a37a37..ef657f1 100644 --- a/sys/netnatm/natm_proto.c +++ b/sys/netnatm/natm_proto.c @@ -123,6 +123,8 @@ void natm_init() LIST_INIT(&natm_pcbs); bzero(&natmintrq, sizeof(natmintrq)); natmintrq.ifq_maxlen = natmqmaxlen; + mtx_init(&natmintrq.ifq_mtx, "natm_inq", MTX_DEF); + } #if defined(__FreeBSD__) diff --git a/sys/netns/ns_input.c b/sys/netns/ns_input.c index a10f99b..4d26a9d 100644 --- a/sys/netns/ns_input.c +++ b/sys/netns/ns_input.c @@ -90,6 +90,7 @@ ns_init() nspcb.nsp_next = nspcb.nsp_prev = &nspcb; nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb; nsintrq.ifq_maxlen = nsqmaxlen; + mtx_init(&nsintrq.ifq_mtx, "ns_inq", MTX_DEF); ns_pexseq = time.tv_usec; ns_netmask.sns_len = 6; ns_netmask.sns_addr.x_net = ns_broadnet; diff --git a/sys/netns/ns_ip.c b/sys/netns/ns_ip.c index 0c5fbeb..45e9b8e 100644 --- a/sys/netns/ns_ip.c +++ b/sys/netns/ns_ip.c @@ -220,17 +220,8 @@ idpip_input(m, ifp) /* * Deliver to NS */ - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); -bad: - m_freem(m); - splx(s); - return; - } - IF_ENQUEUE(ifq, m); - schednetisr(NETISR_NS); - splx(s); + if (IF_HANDOFF(ifq, m, NULL)) + schednetisr(NETISR_NS); return; } diff --git a/sys/pc98/cbus/olpt.c b/sys/pc98/cbus/olpt.c index cd64512..a2c7fe6 100644 --- a/sys/pc98/cbus/olpt.c +++ b/sys/pc98/cbus/olpt.c @@ -1161,18 +1161,15 @@ lpintr (int unit) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf(("DROP")); - IF_DROP(&ipintrq); - goto done; - } len -= CLPIPHDRLEN; sc->sc_if.if_ipackets++; sc->sc_if.if_ibytes += len; top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, &sc->sc_if, 0); if (top) { - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) + lprintf(("DROP")); + else + schednetisr(NETISR_IP); } goto done; } @@ -1210,11 +1207,6 @@ lpintr (int unit) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf(("DROP")); - IF_DROP(&ipintrq); - goto done; - } if (sc->sc_if.if_bpf) { bpf_tap(&sc->sc_if, sc->sc_ifbuf, len); } @@ -1223,8 +1215,10 @@ lpintr (int unit) sc->sc_if.if_ibytes += len; top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, &sc->sc_if, 0); if (top) { - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) + lprintf(("DROP")); + else + schednetisr(NETISR_IP); } } goto done; diff --git a/sys/pc98/pc98/olpt.c b/sys/pc98/pc98/olpt.c index cd64512..a2c7fe6 100644 --- a/sys/pc98/pc98/olpt.c +++ b/sys/pc98/pc98/olpt.c @@ -1161,18 +1161,15 @@ lpintr (int unit) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf(("DROP")); - IF_DROP(&ipintrq); - goto done; - } len -= CLPIPHDRLEN; sc->sc_if.if_ipackets++; sc->sc_if.if_ibytes += len; top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, &sc->sc_if, 0); if (top) { - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) + lprintf(("DROP")); + else + schednetisr(NETISR_IP); } goto done; } @@ -1210,11 +1207,6 @@ lpintr (int unit) sc->sc_iferrs = 0; - if (IF_QFULL(&ipintrq)) { - lprintf(("DROP")); - IF_DROP(&ipintrq); - goto done; - } if (sc->sc_if.if_bpf) { bpf_tap(&sc->sc_if, sc->sc_ifbuf, len); } @@ -1223,8 +1215,10 @@ lpintr (int unit) sc->sc_if.if_ibytes += len; top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, &sc->sc_if, 0); if (top) { - IF_ENQUEUE(&ipintrq, top); - schednetisr(NETISR_IP); + if (! IF_HANDOFF(&ipintrq, top, NULL)) + lprintf(("DROP")); + else + schednetisr(NETISR_IP); } } goto done; diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index aa624cd..108518e 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -3201,7 +3201,7 @@ tulip_reset( bus_dmamap_t map; #endif struct mbuf *m; - IF_DEQUEUE(&sc->tulip_txq, m); + _IF_DEQUEUE(&sc->tulip_txq, m); if (m == NULL) break; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) @@ -3247,7 +3247,7 @@ tulip_reset( bus_dmamap_t map; #endif struct mbuf *m; - IF_DEQUEUE(&sc->tulip_rxq, m); + _IF_DEQUEUE(&sc->tulip_rxq, m); if (m == NULL) break; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX) @@ -3382,7 +3382,7 @@ tulip_rx_intr( */ TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop)); if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) { - IF_DEQUEUE(&sc->tulip_rxq, ms); + _IF_DEQUEUE(&sc->tulip_rxq, ms); me = ms; } else { /* @@ -3422,7 +3422,7 @@ tulip_rx_intr( * won't go into the loop and thereby saving a ourselves from * doing a multiplication by 0 in the normal case). */ - IF_DEQUEUE(&sc->tulip_rxq, ms); + _IF_DEQUEUE(&sc->tulip_rxq, ms); for (me = ms; total_len > 0; total_len--) { #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX) map = M_GETCTX(me, bus_dmamap_t); @@ -3435,7 +3435,7 @@ tulip_rx_intr( #endif /* TULIP_BUS_DMA */ me->m_len = TULIP_RX_BUFLEN; last_offset += TULIP_RX_BUFLEN; - IF_DEQUEUE(&sc->tulip_rxq, me->m_next); + _IF_DEQUEUE(&sc->tulip_rxq, me->m_next); me = me->m_next; } } @@ -3644,7 +3644,7 @@ tulip_rx_intr( ri->ri_nextout = ri->ri_first; me = ms->m_next; ms->m_next = NULL; - IF_ENQUEUE(&sc->tulip_rxq, ms); + _IF_ENQUEUE(&sc->tulip_rxq, ms); } while ((ms = me) != NULL); if (sc->tulip_rxq.ifq_len >= TULIP_RXQ_TARGET) @@ -3702,7 +3702,7 @@ tulip_tx_intr( } } else { const u_int32_t d_status = ri->ri_nextin->d_status; - IF_DEQUEUE(&sc->tulip_txq, m); + _IF_DEQUEUE(&sc->tulip_txq, m); if (m != NULL) { #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t); @@ -4343,7 +4343,7 @@ tulip_txput( * The descriptors have been filled in. Now get ready * to transmit. */ - IF_ENQUEUE(&sc->tulip_txq, m); + _IF_ENQUEUE(&sc->tulip_txq, m); m = NULL; /* diff --git a/sys/pci/if_wxvar.h b/sys/pci/if_wxvar.h index 71fec0e..c665ef0 100644 --- a/sys/pci/if_wxvar.h +++ b/sys/pci/if_wxvar.h @@ -375,8 +375,12 @@ typedef struct wx_softc { wxtd_t *tdescriptors; /* transmit descriptor ring */ u_int16_t tnxtfree; /* next free index (circular) */ u_int16_t tactive; /* # active */ + struct mtx wx_mtx; } wx_softc_t; +#define WX_LOCK(_sc) mtx_enter(&(_sc)->wx_mtx, MTX_DEF) +#define WX_UNLOCK(_sc) mtx_exit(&(_sc)->wx_mtx, MTX_DEF) + /* * We offset the the receive frame header by two bytes so that the actual * payload is 32 bit aligned. On platforms that require strict structure -- cgit v1.1