Page MenuHomeFreeBSD

D53071.diff
No OneTemporary

D53071.diff

diff --git a/sys/net/ifq.c b/sys/net/ifq.c
--- a/sys/net/ifq.c
+++ b/sys/net/ifq.c
@@ -62,16 +62,21 @@
void
drbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m_new)
{
+ int error = 0;
/*
* The top of the list needs to be swapped
- * for this one.
+ * for this one.
+ * In case the mbuf was taken from interface queue
+ * the buf_ring is empty and enqueue needs to be used.
*/
- if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd) && buf_ring_empty(br)) {
/*
* Peek in altq case dequeued it
* so put it back.
*/
- IFQ_DRV_PREPEND(&ifp->if_snd, m_new);
+ error = buf_ring_enqueue(br, m_new);
+ if (error)
+ m_freem(m_new);
return;
}
buf_ring_putback_sc(br, m_new);
@@ -80,18 +85,18 @@
struct mbuf *
drbr_peek(struct ifnet *ifp, struct buf_ring *br)
{
- struct mbuf *m;
- if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ struct mbuf *m = ((struct mbuf *)buf_ring_peek_clear_sc(br));
+ if (m == NULL && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
/*
* Pull it off like a dequeue
* since drbr_advance() does nothing
* for altq and drbr_putback() will
- * use the old prepend function.
+ * use the buf_ring for storing frames.
*/
IFQ_DEQUEUE(&ifp->if_snd, m);
return (m);
}
- return ((struct mbuf *)buf_ring_peek_clear_sc(br));
+ return (m);
}
void
@@ -108,21 +113,22 @@
struct mbuf *
drbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
{
- struct mbuf *m;
+ struct mbuf *m = ((struct mbuf *)buf_ring_dequeue_sc(br));
- if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ if (m == NULL && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
IFQ_DEQUEUE(&ifp->if_snd, m);
return (m);
}
- return ((struct mbuf *)buf_ring_dequeue_sc(br));
+ return (m);
}
void
drbr_advance(struct ifnet *ifp, struct buf_ring *br)
{
- /* Nothing to do here since peek dequeues in altq case */
- if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
- return;
+ /*
+ * Always try to advance buf_ring as it could have been used for putback
+ * and then peek (it does nothing on empty buf_ring)
+ */
return (buf_ring_advance_sc(br));
}
@@ -130,8 +136,8 @@
drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
int (*func) (struct mbuf *, void *), void *arg)
{
- struct mbuf *m;
- if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ struct mbuf *m = (struct mbuf *)buf_ring_peek(br);
+ if (m == NULL && ifp != NULL && 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) {
@@ -142,7 +148,6 @@
IFQ_UNLOCK(&ifp->if_snd);
return (m);
}
- m = (struct mbuf *)buf_ring_peek(br);
if (m == NULL || func(m, arg) == 0)
return (NULL);
@@ -152,9 +157,10 @@
int
drbr_empty(struct ifnet *ifp, struct buf_ring *br)
{
- if (ALTQ_IS_ENABLED(&ifp->if_snd))
+ bool empty = buf_ring_empty(br);
+ if (empty && ALTQ_IS_ENABLED(&ifp->if_snd))
return (IFQ_IS_EMPTY(&ifp->if_snd));
- return (buf_ring_empty(br));
+ return (empty);
}
int
@@ -168,8 +174,9 @@
int
drbr_inuse(struct ifnet *ifp, struct buf_ring *br)
{
+ int count = buf_ring_count(br);
if (ALTQ_IS_ENABLED(&ifp->if_snd))
- return (ifp->if_snd.ifq_len);
- return (buf_ring_count(br));
+ count += (ifp->if_snd.ifq_len);
+ return (count);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 1, 1:23 AM (14 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29089798
Default Alt Text
D53071.diff (3 KB)

Event Timeline