Much to my surprise, IFQ_DRV_DEQUEUE() can return a null mbuf even if
!IFQ_DRV_IS_EMPTY(). Taking this into account, I re-structured the transmit routine so as to avoid adding another if/then in the critical path. Thanks to brueffer for showing my how to test with altq/pf.
This commit is contained in:
parent
dea060ff55
commit
6d914a32ff
@ -1277,32 +1277,30 @@ mxge_encap(mxge_softc_t *sc, struct mbuf *m)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
|
||||
|
||||
static inline void
|
||||
mxge_start_locked(mxge_softc_t *sc)
|
||||
{
|
||||
int avail;
|
||||
struct mbuf *m;
|
||||
struct ifnet *ifp;
|
||||
|
||||
|
||||
ifp = sc->ifp;
|
||||
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||
/* dequeue the packet */
|
||||
while ((sc->tx.mask - (sc->tx.req - sc->tx.done))
|
||||
> MXGE_MAX_SEND_DESC) {
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
|
||||
if (m == NULL) {
|
||||
return;
|
||||
}
|
||||
/* let BPF see it */
|
||||
BPF_MTAP(ifp, m);
|
||||
|
||||
/* give it to the nic */
|
||||
mxge_encap(sc, m);
|
||||
|
||||
/* leave an extra slot keep the ring from wrapping */
|
||||
avail = sc->tx.mask - (sc->tx.req - sc->tx.done);
|
||||
if (avail < MXGE_MAX_SEND_DESC) {
|
||||
sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* ran out of transmit slots */
|
||||
sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user