mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:19:34 +02:00
sched_ext: Reject setting disallow from init_task outside the enable path
The p->scx.disallow revert assumes the root enable path, where the switching
loop reads the reverted policy right afterwards and leaves the task off SCX.
The sub-scheduler disable path also reaches it when re-initializing the
returned tasks on a root parent. Nothing reads the policy there: the task is
enabled on root anyway and keeps running on the ext class with a silently
rewritten policy.
Kill the sched instead, matching the fork and non-root branches, and update
the disallow documentation, which equated !fork with the load path and
pointed at a stale debugfs path for nr_rejected.
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:
@@ -244,11 +244,11 @@ struct sched_ext_entity {
|
||||
* to %SCHED_EXT with -%EACCES.
|
||||
*
|
||||
* Can be set from ops.init_task() while the BPF scheduler is being
|
||||
* loaded (!scx_init_task_args->fork). If set and the task's policy is
|
||||
* already %SCHED_EXT, the task's policy is rejected and forcefully
|
||||
* reverted to %SCHED_NORMAL. The number of such events are reported
|
||||
* through /sys/kernel/debug/sched_ext::nr_rejected. Setting this flag
|
||||
* during fork is not allowed.
|
||||
* loaded. If set and the task's policy is already %SCHED_EXT, the
|
||||
* task's policy is rejected and forcefully reverted to %SCHED_NORMAL.
|
||||
* The number of such events are reported through
|
||||
* /sys/kernel/sched_ext/nr_rejected. Setting this flag from any other
|
||||
* ops.init_task() invocation, such as during fork, fails the scheduler.
|
||||
*/
|
||||
bool disallow; /* reject switching into SCX */
|
||||
|
||||
|
||||
@@ -3606,6 +3606,9 @@ static int __scx_init_task(struct scx_sched *sch, struct task_struct *p, bool fo
|
||||
} else if (unlikely(fork)) {
|
||||
scx_error(sch, "ops.init_task() set task->scx.disallow for %s[%d] during fork",
|
||||
p->comm, p->pid);
|
||||
} else if (unlikely(scx_enable_state() != SCX_ENABLING)) {
|
||||
scx_error(sch, "ops.init_task() set task->scx.disallow for %s[%d] outside the enable path",
|
||||
p->comm, p->pid);
|
||||
} else {
|
||||
struct rq *rq;
|
||||
struct rq_flags rf;
|
||||
|
||||
Reference in New Issue
Block a user