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: c5ad119fb6
("net: sched: pfifo_fast use skb_array")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
5dd431b6b9
commit
e5f0e8f8e4
@@ -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,
|
||||
sch_tree_lock(sch);
|
||||
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);
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
return old;
|
||||
|
Reference in New Issue
Block a user