]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
sched_ext: Don't kick CPUs running higher classes
authorTejun Heo <tj@kernel.org>
Thu, 29 Jan 2026 09:25:45 +0000 (09:25 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Feb 2026 15:57:45 +0000 (16:57 +0100)
commit a9c1fbbd6dadbaa38c157a07d5d11005460b86b9 upstream.

When a sched_ext scheduler tries to kick a CPU, the CPU may be running a
higher class task. sched_ext has no control over such CPUs. A sched_ext
scheduler couldn't have expected to get access to the CPU after kicking it
anyway. Skip kicking when the target CPU is running a higher class.

Reviewed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/sched/ext.c

index 31eda2a56920dc38e5c3270822206cfab09e1e8e..3d53b22329379e88025f3156679805be90ddbdac 100644 (file)
@@ -5164,18 +5164,23 @@ static bool kick_one_cpu(s32 cpu, struct rq *this_rq, unsigned long *pseqs)
 {
        struct rq *rq = cpu_rq(cpu);
        struct scx_rq *this_scx = &this_rq->scx;
+       const struct sched_class *cur_class;
        bool should_wait = false;
        unsigned long flags;
 
        raw_spin_rq_lock_irqsave(rq, flags);
+       cur_class = rq->curr->sched_class;
 
        /*
         * During CPU hotplug, a CPU may depend on kicking itself to make
-        * forward progress. Allow kicking self regardless of online state.
+        * forward progress. Allow kicking self regardless of online state. If
+        * @cpu is running a higher class task, we have no control over @cpu.
+        * Skip kicking.
         */
-       if (cpu_online(cpu) || cpu == cpu_of(this_rq)) {
+       if ((cpu_online(cpu) || cpu == cpu_of(this_rq)) &&
+           !sched_class_above(cur_class, &ext_sched_class)) {
                if (cpumask_test_cpu(cpu, this_scx->cpus_to_preempt)) {
-                       if (rq->curr->sched_class == &ext_sched_class)
+                       if (cur_class == &ext_sched_class)
                                rq->curr->scx.slice = 0;
                        cpumask_clear_cpu(cpu, this_scx->cpus_to_preempt);
                }