From 8ab7420a12769ff5c484db8e40550ef43ab63ede Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Fri, 26 Aug 2022 09:39:30 +0800 Subject: [PATCH] net: sched: tbf: don't call qdisc_put() while holding tree lock [ Upstream commit d2c5796683dfa61a1e176e0943d60b44fa5c456b ] The issue is the same to commit a15da784f8b0 ("net: sched: multiq: don't call qdisc_put() while holding tree lock"). Qdiscs call qdisc_put() while holding sch tree spinlock, which results sleeping-while-atomic BUG. Fixes: d30d424a9fdb ("net: sched: protect block state with mutex") Signed-off-by: Zhengchao Shao Link: https://lore.kernel.org/r/20220826013930.340121-1-shaozhengchao@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/sched/sch_tbf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 5f72f3f916a5a..a7f60bb2dd513 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -297,6 +297,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, struct nlattr *tb[TCA_TBF_MAX + 1]; struct tc_tbf_qopt *qopt; struct Qdisc *child = NULL; + struct Qdisc *old = NULL; struct psched_ratecfg rate; struct psched_ratecfg peak; u64 max_size; @@ -388,7 +389,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, sch_tree_lock(sch); if (child) { qdisc_tree_flush_backlog(q->qdisc); - qdisc_put(q->qdisc); + old = q->qdisc; q->qdisc = child; } q->limit = qopt->limit; @@ -408,6 +409,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg)); sch_tree_unlock(sch); + qdisc_put(old); err = 0; done: return err; -- 2.39.5