[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <4a04e0cc-a64b-44e7-9213-2880ed641d77@sabinyo.mountain>
Date: Thu, 17 Jul 2025 11:51:43 -0500
From: Dan Carpenter <dan.carpenter@...aro.org>
To: Xiang Mei <xmei5@....edu>
Cc: netdev@...r.kernel.org
Subject: [bug report] net/sched: sch_qfq: Fix race condition on qfq_aggregate
Hello Xiang Mei,
Commit 5e28d5a3f774 ("net/sched: sch_qfq: Fix race condition on
qfq_aggregate") from Jul 10, 2025 (linux-next), leads to the
following Smatch static checker warning:
net/sched/sch_generic.c:1107 qdisc_put()
warn: sleeping in atomic context
547 static int qfq_delete_class(struct Qdisc *sch, unsigned long arg,
548 struct netlink_ext_ack *extack)
549 {
550 struct qfq_sched *q = qdisc_priv(sch);
551 struct qfq_class *cl = (struct qfq_class *)arg;
552
553 if (qdisc_class_in_use(&cl->common)) {
554 NL_SET_ERR_MSG_MOD(extack, "QFQ class in use");
555 return -EBUSY;
556 }
557
558 sch_tree_lock(sch);
559
560 qdisc_purge_queue(cl->qdisc);
561 qdisc_class_hash_remove(&q->clhash, &cl->common);
562 qfq_destroy_class(sch, cl);
^^^^^^^^^^^^^^^^^
We used to unlock first and then did the destroy but the patch moved
this qfq_destroy_class() under the sch_tree_unlock() to solve a race
condition. Unfortunately, it introduces a sleeping in atomic context.
563
564 sch_tree_unlock(sch);
565
566 return 0;
567 }
The call tree is:
qfq_delete_class() <- disables preempt
-> qfq_destroy_class()
-> qdisc_put() <- sleeps
net/sched/sch_generic.c
1098 void qdisc_put(struct Qdisc *qdisc)
1099 {
1100 if (!qdisc)
1101 return;
1102
1103 if (qdisc->flags & TCQ_F_BUILTIN ||
1104 !refcount_dec_and_test(&qdisc->refcnt))
1105 return;
1106
--> 1107 __qdisc_destroy(qdisc);
It's the lockdep_unregister_key() call which sleeps.
1108 }
regards,
dan carpenter
Powered by blists - more mailing lists