From: Tao Cui scx_bpf_dsq_reenq() queues a deferred reenq (dru) that runs from run_deferred(), not ops.dispatch(). If the DSQ is destroyed before the dru runs, process_deferred_reenq_users() sees dsq->id == SCX_DSQ_INVALID and hits the BUG_ON. destroy_dsq() doesn't flush pending drus, so just skip. Fixes: 84b1a0ea0b7c ("sched_ext: Implement scx_bpf_dsq_reenq() for user DSQs") Signed-off-by: Tao Cui --- Change in v2: Only skip SCX_DSQ_INVALID and keep the BUG_ON for other builtin ids instead of skipping every builtin-flagged id, per Tejun. --- kernel/sched/ext/ext.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c index 26dbbbfe5a87..7d097209e778 100644 --- a/kernel/sched/ext/ext.c +++ b/kernel/sched/ext/ext.c @@ -4637,6 +4637,10 @@ static void process_deferred_reenq_users(struct rq *rq) /* see schedule_dsq_reenq() */ smp_mb(); + /* destroy_dsq() may have raced and invalidated @dsq, nothing to reenq */ + if (unlikely(dsq->id == SCX_DSQ_INVALID)) + continue; + BUG_ON(dsq->id & SCX_DSQ_FLAG_BUILTIN); reenq_user(rq, dsq, reenq_flags); } -- 2.43.0