summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2000-11-25 07:35:38 +0000
committerjlemon <jlemon@FreeBSD.org>2000-11-25 07:35:38 +0000
commit954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85 (patch)
tree0a4e9f6dcd5fa64a78f5991ac425f3ca97aba154 /sys
parent2daca11cae375091daf49a7cd704e5e4e1be27db (diff)
downloadFreeBSD-src-954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85.zip
FreeBSD-src-954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c12
-rw-r--r--sys/dev/ar/if_ar.c11
-rw-r--r--sys/dev/ar/if_ar_isa.c11
-rw-r--r--sys/dev/awi/awi.c19
-rw-r--r--sys/dev/de/if_de.c16
-rw-r--r--sys/dev/en/midway.c26
-rw-r--r--sys/dev/hea/eni_receive.c16
-rw-r--r--sys/dev/hea/eni_transmit.c10
-rw-r--r--sys/dev/hfa/fore_receive.c4
-rw-r--r--sys/dev/iicbus/if_ic.c9
-rw-r--r--sys/dev/lmc/if_lmc.c23
-rw-r--r--sys/dev/lmc/if_lmc_common.c4
-rw-r--r--sys/dev/pdq/pdq_ifsubr.c8
-rw-r--r--sys/dev/ppbus/if_plip.c24
-rw-r--r--sys/dev/sr/if_sr.c11
-rw-r--r--sys/dev/sr/if_sr_isa.c11
-rw-r--r--sys/dev/usb/udbp.c23
-rw-r--r--sys/dev/usb/usb_ethersubr.c14
-rw-r--r--sys/i386/isa/if_ar.c11
-rw-r--r--sys/i386/isa/if_sr.c11
-rw-r--r--sys/i4b/driver/i4b_bsdi_ibc.c23
-rw-r--r--sys/i4b/driver/i4b_ing.c36
-rw-r--r--sys/i4b/driver/i4b_ipr.c50
-rw-r--r--sys/i4b/driver/i4b_isppp.c7
-rw-r--r--sys/i4b/driver/i4b_ispppsubr.c63
-rw-r--r--sys/i4b/driver/i4b_rbch.c43
-rw-r--r--sys/i4b/driver/i4b_tel.c32
-rw-r--r--sys/i4b/driver/i4b_trace.c17
-rw-r--r--sys/i4b/layer1/ifpi/i4b_ifpi_pci.c19
-rw-r--r--sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c19
-rw-r--r--sys/i4b/layer1/ihfc/i4b_ihfc_drv.c9
-rw-r--r--sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c4
-rw-r--r--sys/i4b/layer1/isic/i4b_bchan.c10
-rw-r--r--sys/i4b/layer1/isic/i4b_hscx.c9
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_bchan.c19
-rw-r--r--sys/i4b/layer2/i4b_l2.c3
-rw-r--r--sys/i4b/layer2/i4b_mbuf.c16
-rw-r--r--sys/i4b/layer2/i4b_util.c2
-rw-r--r--sys/i4b/layer4/i4b_i4bdrv.c27
-rw-r--r--sys/net/bridge.c16
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if_atmsubr.c21
-rw-r--r--sys/net/if_ef.c18
-rw-r--r--sys/net/if_ethersubr.c38
-rw-r--r--sys/net/if_fddisubr.c28
-rw-r--r--sys/net/if_gif.c16
-rw-r--r--sys/net/if_iso88025subr.c31
-rw-r--r--sys/net/if_loop.c26
-rw-r--r--sys/net/if_ppp.c99
-rw-r--r--sys/net/if_sl.c18
-rw-r--r--sys/net/if_spppsubr.c69
-rw-r--r--sys/net/if_stf.c14
-rw-r--r--sys/net/if_tun.c31
-rw-r--r--sys/net/if_var.h149
-rw-r--r--sys/net/if_vlan.c14
-rw-r--r--sys/net/intrq.c11
-rw-r--r--sys/netatalk/ddp_pcb.c2
-rw-r--r--sys/netatalk/ddp_usrreq.c2
-rw-r--r--sys/netatm/atm_device.c2
-rw-r--r--sys/netatm/atm_subr.c1
-rw-r--r--sys/netatm/ipatm/ipatm_input.c11
-rw-r--r--sys/netinet/if_ether.c13
-rw-r--r--sys/netinet/ip_auth.c12
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet/ip_mroute.c12
-rw-r--r--sys/netinet6/ah_input.c15
-rw-r--r--sys/netinet6/esp_input.c15
-rw-r--r--sys/netinet6/ip6_input.c1
-rw-r--r--sys/netipx/ipx_input.c1
-rw-r--r--sys/netipx/ipx_ip.c12
-rw-r--r--sys/netnatm/natm_proto.c2
-rw-r--r--sys/netns/ns_input.c1
-rw-r--r--sys/netns/ns_ip.c13
-rw-r--r--sys/pc98/cbus/olpt.c22
-rw-r--r--sys/pc98/pc98/olpt.c22
-rw-r--r--sys/pci/if_de.c16
-rw-r--r--sys/pci/if_wxvar.h4
77 files changed, 587 insertions, 890 deletions
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 <sys/queue.h> /* get TAILQ macros */
+#include <sys/mbuf.h>
+#include <machine/mutex.h>
+
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
OpenPOWER on IntegriCloud