diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-11-06 01:02:34 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-06 01:02:34 +0100 |
commit | 61c9eaf90081cbe6dc4f389e0056bff76eca19ec (patch) | |
tree | 4122787f6a424c75de5f7562e84ccf34ca37251a | |
parent | net: Don't leak packets when a netns is going down (diff) | |
download | linux-61c9eaf90081cbe6dc4f389e0056bff76eca19ec.tar.xz linux-61c9eaf90081cbe6dc4f389e0056bff76eca19ec.zip |
pkt_sched: Fix qdisc len in qdisc_peek_dequeued()
A packet dequeued and stored as gso_skb in qdisc_peek_dequeued() should
be seen as part of the queue for sch->q.qlen queries until it's really
dequeued with qdisc_dequeue_peeked(), so qlen needs additional updating
in these functions. (Updating qstats.backlog shouldn't matter here.)
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sch_generic.h | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 9dcb5bfe094a..64ae1ba9f554 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -442,8 +442,12 @@ static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch) static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch) { /* we can reuse ->gso_skb because peek isn't called for root qdiscs */ - if (!sch->gso_skb) + if (!sch->gso_skb) { sch->gso_skb = sch->dequeue(sch); + if (sch->gso_skb) + /* it's still part of the queue */ + sch->q.qlen++; + } return sch->gso_skb; } @@ -453,10 +457,12 @@ static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch) { struct sk_buff *skb = sch->gso_skb; - if (skb) + if (skb) { sch->gso_skb = NULL; - else + sch->q.qlen--; + } else { skb = sch->dequeue(sch); + } return skb; } |