61 lines
2.0 KiB
Diff
61 lines
2.0 KiB
Diff
From 77f4f1ca7b68d33c3841e740ae6b03378a77d281 Mon Sep 17 00:00:00 2001
|
|
From: Andrea Righi <arighi@nvidia.com>
|
|
Date: Tue, 5 Aug 2025 10:59:11 +0200
|
|
Subject: sched/ext: Fix invalid task state transitions on class switch
|
|
|
|
When enabling a sched_ext scheduler, we may trigger invalid task state
|
|
transitions, resulting in warnings like the following (which can be
|
|
easily reproduced by running the hotplug selftest in a loop):
|
|
|
|
sched_ext: Invalid task state transition 0 -> 3 for fish[770]
|
|
WARNING: CPU: 18 PID: 787 at kernel/sched/ext.c:3862 scx_set_task_state+0x7c/0xc0
|
|
...
|
|
RIP: 0010:scx_set_task_state+0x7c/0xc0
|
|
...
|
|
Call Trace:
|
|
<TASK>
|
|
scx_enable_task+0x11f/0x2e0
|
|
switching_to_scx+0x24/0x110
|
|
scx_enable.isra.0+0xd14/0x13d0
|
|
bpf_struct_ops_link_create+0x136/0x1a0
|
|
__sys_bpf+0x1edd/0x2c30
|
|
__x64_sys_bpf+0x21/0x30
|
|
do_syscall_64+0xbb/0x370
|
|
entry_SYSCALL_64_after_hwframe+0x77/0x7f
|
|
|
|
This happens because we skip initialization for tasks that are already
|
|
dead (with their usage counter set to zero), but we don't exclude them
|
|
during the scheduling class transition phase.
|
|
|
|
Fix this by also skipping dead tasks during class swiching, preventing
|
|
invalid task state transitions.
|
|
|
|
Fixes: a8532fac7b5d2 ("sched_ext: TASK_DEAD tasks must be switched into SCX on ops_enable")
|
|
Cc: stable@vger.kernel.org # v6.12+
|
|
Signed-off-by: Andrea Righi <arighi@nvidia.com>
|
|
Signed-off-by: Tejun Heo <tj@kernel.org>
|
|
---
|
|
kernel/sched/ext.c | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
--- a/kernel/sched/ext.c
|
|
+++ b/kernel/sched/ext.c
|
|
@@ -5694,6 +5694,9 @@ static int scx_enable(struct sched_ext_o
|
|
__setscheduler_class(p->policy, p->prio);
|
|
struct sched_enq_and_set_ctx ctx;
|
|
|
|
+ if (!tryget_task_struct(p))
|
|
+ continue;
|
|
+
|
|
if (old_class != new_class && p->se.sched_delayed)
|
|
dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
|
|
|
|
@@ -5706,6 +5709,7 @@ static int scx_enable(struct sched_ext_o
|
|
sched_enq_and_set_task(&ctx);
|
|
|
|
check_class_changed(task_rq(p), p, old_class, p->prio);
|
|
+ put_task_struct(p);
|
|
}
|
|
scx_task_iter_stop(&sti);
|
|
percpu_up_write(&scx_fork_rwsem);
|