mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 22:54:17 -04:00
sched_ext: Don't enable non-ext tasks in the sub-sched task loops
Root enable and scx_post_fork() enable a task only if it's on the ext class.
Tasks on other classes, possible under an SCX_OPS_SWITCH_PARTIAL root, are
left READY and enabled by switching_to_scx() when they switch over. The sub
enable-commit pass and the sub-disable re-home loop enable unconditionally,
so a fair-class READY task in the subtree becomes ENABLED while not on
sched_ext. A later switch to SCHED_EXT then trips the task state validation
WARN (ENABLED with the previous state not READY) and calls ops.enable() a
second time.
Gate scx_enable_task() on the task's class in both loops.
Fixes: 337ec00b1d ("sched_ext: Implement cgroup sub-sched enabling and disabling")
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
This commit is contained in:
@@ -6010,15 +6010,22 @@ static void scx_sub_disable(struct scx_sched *sch)
|
||||
/*
|
||||
* $p is initialized for $parent and still attached to
|
||||
* @sch. Disable and exit for @sch, switch over to
|
||||
* $parent, override the state to READY to account for
|
||||
* $p having already been initialized, and then enable.
|
||||
* $parent and override the state to READY to account
|
||||
* for $p having already been initialized.
|
||||
*/
|
||||
scx_disable_and_exit_task(sch, p);
|
||||
scx_set_task_state(p, SCX_TASK_INIT_BEGIN);
|
||||
scx_set_task_state(p, SCX_TASK_INIT);
|
||||
scx_set_task_sched(p, parent);
|
||||
scx_set_task_state(p, SCX_TASK_READY);
|
||||
scx_enable_task(parent, p);
|
||||
|
||||
/*
|
||||
* A task on a non-ext class, possible under an
|
||||
* %SCX_OPS_SWITCH_PARTIAL root, stays READY and is
|
||||
* enabled by switching_to_scx() if it switches over.
|
||||
*/
|
||||
if (p->sched_class == &ext_sched_class)
|
||||
scx_enable_task(parent, p);
|
||||
}
|
||||
|
||||
task_rq_unlock(rq, p, &rf);
|
||||
@@ -7726,10 +7733,14 @@ static void scx_sub_enable_workfn(struct kthread_work *work)
|
||||
|
||||
/*
|
||||
* $p is now only initialized for @sch and READY, which
|
||||
* is what we want. Assign it to @sch and enable.
|
||||
* is what we want. Assign it to @sch and, if it's on
|
||||
* the ext class, enable. A non-ext task, possible under
|
||||
* an %SCX_OPS_SWITCH_PARTIAL root, stays READY and is
|
||||
* enabled by switching_to_scx() if it switches over.
|
||||
*/
|
||||
scx_set_task_sched(p, sch);
|
||||
scx_enable_task(sch, p);
|
||||
if (p->sched_class == &ext_sched_class)
|
||||
scx_enable_task(sch, p);
|
||||
|
||||
p->scx.flags &= ~SCX_TASK_SUB_INIT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user