diff --git a/sys/net/ifq.h b/sys/net/ifq.h --- a/sys/net/ifq.h +++ b/sys/net/ifq.h @@ -262,7 +262,7 @@ #define IFQ_HANDOFF(ifp, m, err) \ IFQ_HANDOFF_ADJ(ifp, m, 0, err) -#define IFQ_DRV_DEQUEUE(ifq, m) \ +#define IFQ_DRV_DEQUEUE_INTERNAL(ifq, m) \ do { \ (m) = (ifq)->ifq_drv_head; \ if (m) { \ @@ -270,22 +270,41 @@ (ifq)->ifq_drv_tail = NULL; \ (m)->m_nextpkt = NULL; \ (ifq)->ifq_drv_len--; \ - } else { \ + } \ +} while (0) + +#define IFQ_DRV_DEQUEUE_BATCH(ifq, m) \ +do { \ + IFQ_DEQUEUE_NOLOCK(ifq, m); \ + while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ + struct mbuf *m0; \ + IFQ_DEQUEUE_NOLOCK(ifq, m0); \ + if (m0 == NULL) \ + break; \ + m0->m_nextpkt = NULL; \ + if ((ifq)->ifq_drv_tail == NULL) \ + (ifq)->ifq_drv_head = m0; \ + else \ + (ifq)->ifq_drv_tail->m_nextpkt = m0; \ + (ifq)->ifq_drv_tail = m0; \ + (ifq)->ifq_drv_len++; \ + } \ +} while (0) + +#define IFQ_DRV_DEQUEUE_NOLOCK(ifq, m) \ +do { \ + IFQ_DRV_DEQUEUE_INTERNAL(ifq, m); \ + if (!m) { \ + IFQ_DRV_DEQUEUE_BATCH(ifq, m); \ + } \ +} while (0) + +#define IFQ_DRV_DEQUEUE(ifq, m) \ +do { \ + IFQ_DRV_DEQUEUE_INTERNAL(ifq, m); \ + if (!m) { \ IFQ_LOCK(ifq); \ - IFQ_DEQUEUE_NOLOCK(ifq, m); \ - while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ - struct mbuf *m0; \ - IFQ_DEQUEUE_NOLOCK(ifq, m0); \ - if (m0 == NULL) \ - break; \ - m0->m_nextpkt = NULL; \ - if ((ifq)->ifq_drv_tail == NULL) \ - (ifq)->ifq_drv_head = m0; \ - else \ - (ifq)->ifq_drv_tail->m_nextpkt = m0; \ - (ifq)->ifq_drv_tail = m0; \ - (ifq)->ifq_drv_len++; \ - } \ + IFQ_DRV_DEQUEUE_BATCH(ifq, m); \ IFQ_UNLOCK(ifq); \ } \ } while (0) diff --git a/sys/net/ifq.c b/sys/net/ifq.c --- a/sys/net/ifq.c +++ b/sys/net/ifq.c @@ -90,7 +90,7 @@ * for altq and drbr_putback() will * use the old prepend function. */ - IFQ_DEQUEUE(&ifp->if_snd, m); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); return (m); } return ((struct mbuf *)buf_ring_peek_clear_sc(br)); @@ -102,7 +102,7 @@ struct mbuf *m; if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) - IFQ_PURGE(&ifp->if_snd); + IFQ_DRV_PURGE(&ifp->if_snd); while ((m = (struct mbuf *)buf_ring_dequeue_sc(br)) != NULL) m_freem(m); } @@ -113,7 +113,7 @@ struct mbuf *m; if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { - IFQ_DEQUEUE(&ifp->if_snd, m); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); return (m); } return ((struct mbuf *)buf_ring_dequeue_sc(br)); @@ -135,12 +135,12 @@ struct mbuf *m; if (ALTQ_IS_ENABLED(&ifp->if_snd)) { IFQ_LOCK(&ifp->if_snd); - IFQ_POLL_NOLOCK(&ifp->if_snd, m); + IFQ_DRV_DEQUEUE_NOLOCK(&ifp->if_snd, m); if (m != NULL && func(m, arg) == 0) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); IFQ_UNLOCK(&ifp->if_snd); return (NULL); } - IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m); IFQ_UNLOCK(&ifp->if_snd); return (m); } @@ -155,7 +155,7 @@ drbr_empty(struct ifnet *ifp, struct buf_ring *br) { if (ALTQ_IS_ENABLED(&ifp->if_snd)) - return (IFQ_IS_EMPTY(&ifp->if_snd)); + return (IFQ_DRV_IS_EMPTY(&ifp->if_snd)); return (buf_ring_empty(br)); }