summaryrefslogtreecommitdiffstats
path: root/sys/net/if_var.h
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2010-02-13 16:04:58 +0000
committermlaier <mlaier@FreeBSD.org>2010-02-13 16:04:58 +0000
commitb056acb8640e378c0d878874ce7f56a67b32ac83 (patch)
tree2bbb3c25e16999b1fed53dc0860bb11438c41e07 /sys/net/if_var.h
parent84d671e3911041ffcdd18cb939006fec60e0abec (diff)
downloadFreeBSD-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/if_var.h')
-rw-r--r--sys/net/if_var.h36
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
OpenPOWER on IntegriCloud