Commit a844b0c8 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net_sched-no-longer-use-qdisc_tree_flush_backlog'

Eric Dumazet says:

====================
net_sched: no longer use qdisc_tree_flush_backlog()

This series is based on a report from Gerrard Tai.

Essentially, all users of qdisc_tree_flush_backlog() are racy.

We must instead use qdisc_purge_queue().
====================

Link: https://patch.msgid.link/20250611111515.1983366-1-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7ca52541 adcaa890
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -973,14 +973,6 @@ 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;
+1 −1
Original line number Diff line number Diff line
@@ -661,7 +661,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
	for (i = q->nbands; i < oldbands; i++) {
		if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
			list_del_init(&q->classes[i].alist);
		qdisc_tree_flush_backlog(q->classes[i].qdisc);
		qdisc_purge_queue(q->classes[i].qdisc);
	}
	WRITE_ONCE(q->nstrict, nstrict);
	memcpy(q->prio2band, priomap, sizeof(priomap));
+1 −1
Original line number Diff line number Diff line
@@ -211,7 +211,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
	memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);

	for (i = q->bands; i < oldbands; i++)
		qdisc_tree_flush_backlog(q->queues[i]);
		qdisc_purge_queue(q->queues[i]);

	for (i = oldbands; i < q->bands; i++) {
		q->queues[i] = queues[i];
+1 −1
Original line number Diff line number Diff line
@@ -285,7 +285,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb,
	q->userbits = userbits;
	q->limit = ctl->limit;
	if (child) {
		qdisc_tree_flush_backlog(q->qdisc);
		qdisc_purge_queue(q->qdisc);
		old_child = q->qdisc;
		q->qdisc = child;
	}
+1 −1
Original line number Diff line number Diff line
@@ -452,7 +452,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,

	sch_tree_lock(sch);
	if (child) {
		qdisc_tree_flush_backlog(q->qdisc);
		qdisc_purge_queue(q->qdisc);
		old = q->qdisc;
		q->qdisc = child;
	}