path: root/include/net/sch_generic.h
diff options
authorPaolo Abeni <pabeni@redhat.com>2019-03-28 16:53:13 +0100
committerDavid S. Miller <davem@davemloft.net>2019-04-01 14:50:13 -0700
commite5f0e8f8e456589d56e4955154ed5d468cd6d286 (patch)
tree394e064316a0965588c3784a36a24fca3a7b352d /include/net/sch_generic.h
parentnet: sched: introduce and use qstats read helpers (diff)
net: sched: introduce and use qdisc tree flush/purge helpers
The same code to flush qdisc tree and purge the qdisc queue is duplicated in many places and in most cases it does not respect NOLOCK qdisc: the global backlog len is used and the per CPU values are ignored. This change addresses the above, factoring-out the relevant code and using the helpers introduced by the previous patch to fetch the correct backlog len. Fixes: c5ad119fb6c0 ("net: sched: pfifo_fast use skb_array") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/sch_generic.h')
1 files changed, 19 insertions, 7 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 43e4e17aa938..a2b38b3deeca 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -941,6 +941,23 @@ static inline void qdisc_qstats_qlen_backlog(struct Qdisc *sch, __u32 *qlen,
*backlog = qstats.backlog;
+static inline void qdisc_tree_flush_backlog(struct Qdisc *sch)
+ __u32 qlen, backlog;
+ qdisc_qstats_qlen_backlog(sch, &qlen, &backlog);
+ qdisc_tree_reduce_backlog(sch, qlen, backlog);
+static inline void qdisc_purge_queue(struct Qdisc *sch)
+ __u32 qlen, backlog;
+ qdisc_qstats_qlen_backlog(sch, &qlen, &backlog);
+ qdisc_reset(sch);
+ qdisc_tree_reduce_backlog(sch, qlen, backlog);
static inline void qdisc_skb_head_init(struct qdisc_skb_head *qh)
qh->head = NULL;
@@ -1124,13 +1141,8 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
old = *pold;
*pold = new;
- if (old != NULL) {
- unsigned int qlen = old->q.qlen;
- unsigned int backlog = old->qstats.backlog;
- qdisc_reset(old);
- qdisc_tree_reduce_backlog(old, qlen, backlog);
- }
+ if (old != NULL)
+ qdisc_tree_flush_backlog(old);
return old;