summaryrefslogtreecommitdiffstats
path: root/sys/i4b/driver/i4b_rbch.c
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/i4b/driver/i4b_rbch.c
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/i4b/driver/i4b_rbch.c')
-rw-r--r--sys/i4b/driver/i4b_rbch.c43
1 files changed, 11 insertions, 32 deletions
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;
}
/*---------------------------------------------------------------------------*
OpenPOWER on IntegriCloud