diff options
| author | Tejun Heo <tj@kernel.org> | 2026-03-10 07:12:21 -1000 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-03-10 07:12:21 -1000 |
| commit | 6b4576b09714def33890e04ef49621bca3614bbf (patch) | |
| tree | 7b5b52e341a40fc33eb18801bc7839b406c8b75b /kernel | |
| parent | 6b36c4c2935c54d6a103389fad2a2a9d25591501 (diff) | |
| download | linux-6b4576b09714def33890e04ef49621bca3614bbf.tar.gz linux-6b4576b09714def33890e04ef49621bca3614bbf.zip | |
sched_ext: Reject sub-sched attachment to a disabled parent
scx_claim_exit() propagates exits to descendants under scx_sched_lock.
A sub-sched being attached concurrently could be missed if it links
after the propagation. Check the parent's exit_kind in scx_link_sched()
under scx_sched_lock to interlock against scx_claim_exit() - either the
parent sees the child in its iteration or the child sees the parent's
non-NONE exit_kind and fails attachment.
Fixes: ebeca1f930ea ("sched_ext: Introduce cgroup sub-sched support")
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/ext.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index efba05725139..e7ab3647e35f 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -5247,6 +5247,17 @@ static s32 scx_link_sched(struct scx_sched *sch) s32 ret; if (parent) { + /* + * scx_claim_exit() propagates exit_kind transition to + * its sub-scheds while holding scx_sched_lock - either + * we can see the parent's non-NONE exit_kind or the + * parent can shoot us down. + */ + if (atomic_read(&parent->exit_kind) != SCX_EXIT_NONE) { + scx_error(sch, "parent disabled"); + return -ENOENT; + } + ret = rhashtable_lookup_insert_fast(&scx_sched_hash, &sch->hash_node, scx_sched_hash_params); if (ret) { @@ -5638,6 +5649,11 @@ static bool scx_claim_exit(struct scx_sched *sch, enum scx_exit_kind kind) * serialized, running them in separate threads allows parallelizing * ops.exit(), which can take arbitrarily long prolonging bypass mode. * + * To guarantee forward progress, this propagation must be in-line so + * that ->aborting is synchronously asserted for all sub-scheds. The + * propagation is also the interlocking point against sub-sched + * attachment. See scx_link_sched(). + * * This doesn't cause recursions as propagation only takes place for * non-propagation exits. */ |
