diff options
author | mlaier <mlaier@FreeBSD.org> | 2010-02-13 16:04:58 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2010-02-13 16:04:58 +0000 |
commit | b056acb8640e378c0d878874ce7f56a67b32ac83 (patch) | |
tree | 2bbb3c25e16999b1fed53dc0860bb11438c41e07 /sys/net | |
parent | 84d671e3911041ffcdd18cb939006fec60e0abec (diff) | |
download | FreeBSD-src-b056acb8640e378c0d878874ce7f56a67b32ac83.zip FreeBSD-src-b056acb8640e378c0d878874ce7f56a67b32ac83.tar.gz |
Fix drbr and altq interaction:
- introduce drbr_needs_enqueue that returns whether the interface/br needs
an enqueue operation: returns true if altq is enabled or there are
already packets in the ring (as we need to maintain packet order)
- update all drbr consumers
- fix drbr_flush
- avoid using the driver queue (IFQ_DRV_*) in the altq case as the
multiqueue consumer does not provide enough protection, serialize altq
interaction with the main queue lock
- make drbr_dequeue_cond work with altq
Discussed with: kmacy, yongari, jfv
MFC after: 4 weeks
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_var.h | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 37ebea5..4127069 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -603,12 +603,8 @@ drbr_flush(struct ifnet *ifp, struct buf_ring *br) struct mbuf *m; #ifdef ALTQ - if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { - while (!IFQ_IS_EMPTY(&ifp->if_snd)) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - m_freem(m); - } - } + if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) + IFQ_PURGE(&ifp->if_snd); #endif while ((m = buf_ring_dequeue_sc(br)) != NULL) m_freem(m); @@ -629,7 +625,7 @@ drbr_dequeue(struct ifnet *ifp, struct buf_ring *br) struct mbuf *m; if (ALTQ_IS_ENABLED(&ifp->if_snd)) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); return (m); } #endif @@ -642,11 +638,15 @@ drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br, { struct mbuf *m; #ifdef ALTQ - /* - * XXX need to evaluate / requeue - */ - if (ALTQ_IS_ENABLED(&ifp->if_snd)) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (ALTQ_IS_ENABLED(&ifp->if_snd)) { + IFQ_LOCK(&ifp->if_snd); + IFQ_POLL_NOLOCK(&ifp->if_snd, m); + if (m != NULL && func(m, arg) == 0) { + IFQ_UNLOCK(&ifp->if_snd); + return (NULL); + } + IFQ_DEQUEUE(&ifp->if_snd, m); + IFQ_UNLOCK(&ifp->if_snd); return (m); } #endif @@ -662,12 +662,22 @@ drbr_empty(struct ifnet *ifp, struct buf_ring *br) { #ifdef ALTQ if (ALTQ_IS_ENABLED(&ifp->if_snd)) - return (IFQ_DRV_IS_EMPTY(&ifp->if_snd)); + return (IFQ_IS_EMPTY(&ifp->if_snd)); #endif return (buf_ring_empty(br)); } static __inline int +drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br) +{ +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + return (1); +#endif + return (!buf_ring_empty(br)); +} + +static __inline int drbr_inuse(struct ifnet *ifp, struct buf_ring *br) { #ifdef ALTQ |