]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sched_ext: Reject sub-sched attachment to a disabled parent
authorTejun Heo <tj@kernel.org>
Tue, 10 Mar 2026 17:12:21 +0000 (07:12 -1000)
committerTejun Heo <tj@kernel.org>
Tue, 10 Mar 2026 17:12:21 +0000 (07:12 -1000)
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>
kernel/sched/ext.c

index efba05725139a9c37f1891fa121e2bd9cf682999..e7ab3647e35fe6cbdd4c7a0870fac8bf660d2780 100644 (file)
@@ -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.
         */