diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2016-02-25 14:55:01 -0800 |
---|---|---|
committer | Sasha Levin <sasha.levin@oracle.com> | 2016-07-10 23:07:23 -0400 |
commit | 236094acb4b5c224d68d3b279941d24d555078d4 (patch) | |
tree | 37455ca6acbdcd69e4e039c82a1d317cae128dec /include | |
parent | 11316d7eef2230000bb4fa3d4b9056690fda3ef2 (diff) | |
download | lwn-236094acb4b5c224d68d3b279941d24d555078d4.tar.gz lwn-236094acb4b5c224d68d3b279941d24d555078d4.zip |
net_sched: update hierarchical backlog too
[ Upstream commit 2ccccf5fb43ff62b2b96cc58d95fc0b3596516e4 ]
When the bottom qdisc decides to, for example, drop some packet,
it calls qdisc_tree_decrease_qlen() to update the queue length
for all its ancestors, we need to update the backlog too to
keep the stats on root qdisc accurate.
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/codel.h | 4 | ||||
-rw-r--r-- | include/net/sch_generic.h | 5 |
2 files changed, 7 insertions, 2 deletions
diff --git a/include/net/codel.h b/include/net/codel.h index 1e18005f7f65..0ee76108e741 100644 --- a/include/net/codel.h +++ b/include/net/codel.h @@ -160,11 +160,13 @@ struct codel_vars { * struct codel_stats - contains codel shared variables and stats * @maxpacket: largest packet we've seen so far * @drop_count: temp count of dropped packets in dequeue() + * @drop_len: bytes of dropped packets in dequeue() * ecn_mark: number of packets we ECN marked instead of dropping */ struct codel_stats { u32 maxpacket; u32 drop_count; + u32 drop_len; u32 ecn_mark; }; @@ -301,6 +303,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, vars->rec_inv_sqrt); goto end; } + stats->drop_len += qdisc_pkt_len(skb); qdisc_drop(skb, sch); stats->drop_count++; skb = dequeue_func(vars, sch); @@ -323,6 +326,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, if (params->ecn && INET_ECN_set_ce(skb)) { stats->ecn_mark++; } else { + stats->drop_len += qdisc_pkt_len(skb); qdisc_drop(skb, sch); stats->drop_count++; diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1fb8a5b42836..530bdca19803 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -395,7 +395,8 @@ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, struct Qdisc *qdisc); void qdisc_reset(struct Qdisc *qdisc); void qdisc_destroy(struct Qdisc *qdisc); -void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n); +void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n, + unsigned int len); struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, const struct Qdisc_ops *ops); struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, @@ -700,7 +701,7 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new, old = *pold; *pold = new; if (old != NULL) { - qdisc_tree_decrease_qlen(old, old->q.qlen); + qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog); qdisc_reset(old); } sch_tree_unlock(sch); |