]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched_ext: Move aborting flag to per-scheduler field
authorTejun Heo <tj@kernel.org>
Fri, 6 Mar 2026 17:58:03 +0000 (07:58 -1000)
committerTejun Heo <tj@kernel.org>
Fri, 6 Mar 2026 17:58:03 +0000 (07:58 -1000)
The abort state was tracked in the global scx_aborting flag which was used to
break out of potential live-lock scenarios when an error occurs. With
hierarchical scheduling, each scheduler instance must track its own abort
state independently so that an aborting scheduler doesn't interfere with
others.

Move the aborting flag into struct scx_sched and update all access sites. The
early initialization check in scx_root_enable() that warned about residual
aborting state is no longer needed as each scheduler instance now starts with
a clean state.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
kernel/sched/ext.c
kernel/sched/ext_internal.h

index a73a5957e9d9f11da50c3aba24b77f139b05c1e8..47b51bd31a30d1551ed24bca95e13d384cd824ba 100644 (file)
@@ -44,7 +44,6 @@ static atomic_t scx_enable_state_var = ATOMIC_INIT(SCX_DISABLED);
 static int scx_bypass_depth;
 static cpumask_var_t scx_bypass_lb_donee_cpumask;
 static cpumask_var_t scx_bypass_lb_resched_cpumask;
-static bool scx_aborting;
 static bool scx_init_task_enabled;
 static bool scx_switching_all;
 DEFINE_STATIC_KEY_FALSE(__scx_switched_all);
@@ -2151,7 +2150,7 @@ retry:
                 * the system into the bypass mode. This can easily live-lock the
                 * machine. If aborting, exit from all non-bypass DSQs.
                 */
-               if (unlikely(READ_ONCE(scx_aborting)) && dsq->id != SCX_DSQ_BYPASS)
+               if (unlikely(READ_ONCE(sch->aborting)) && dsq->id != SCX_DSQ_BYPASS)
                        break;
 
                if (rq == task_rq) {
@@ -4677,7 +4676,6 @@ static void scx_root_disable(struct scx_sched *sch)
 
        /* guarantee forward progress and wait for descendants to be disabled */
        scx_bypass(true);
-       WRITE_ONCE(scx_aborting, false);
        drain_descendants(sch);
 
        switch (scx_set_enable_state(SCX_DISABLING)) {
@@ -4838,7 +4836,7 @@ static bool scx_claim_exit(struct scx_sched *sch, enum scx_exit_kind kind)
         * flag to break potential live-lock scenarios, ensuring we can
         * successfully reach scx_bypass().
         */
-       WRITE_ONCE(scx_aborting, true);
+       WRITE_ONCE(sch->aborting, true);
 
        /*
         * Propagate exits to descendants immediately. Each has a dedicated
@@ -5485,8 +5483,6 @@ static void scx_root_enable_workfn(struct kthread_work *work)
         */
        WARN_ON_ONCE(scx_set_enable_state(SCX_ENABLING) != SCX_DISABLED);
        WARN_ON_ONCE(scx_root);
-       if (WARN_ON_ONCE(READ_ONCE(scx_aborting)))
-               WRITE_ONCE(scx_aborting, false);
 
        atomic_long_set(&scx_nr_rejected, 0);
 
@@ -6758,7 +6754,7 @@ static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit,
         * If the BPF scheduler keeps calling this function repeatedly, it can
         * cause similar live-lock conditions as consume_dispatch_q().
         */
-       if (unlikely(READ_ONCE(scx_aborting)))
+       if (unlikely(READ_ONCE(sch->aborting)))
                return false;
 
        if (unlikely(!scx_task_on_sched(sch, p))) {
index 6c1eeaaa41db27444987254c685348c668b80344..87f19aed47fb5d416fc9af0e7895b7cea5d92aeb 100644 (file)
@@ -951,6 +951,7 @@ struct scx_sched {
        struct scx_sched_pcpu __percpu *pcpu;
 
        u64                     slice_dfl;
+       bool                    aborting;
        s32                     level;
 
        /*