Merge branch 'for-6.14-fixes' into for-6.15
authorTejun Heo <tj@kernel.org>
Mon, 10 Feb 2025 20:45:43 +0000 (10:45 -1000)
committerTejun Heo <tj@kernel.org>
Mon, 10 Feb 2025 20:45:43 +0000 (10:45 -1000)
Pull to receive f3f08c3acfb8 ("sched_ext: Fix incorrect assumption about
migration disabled tasks in task_can_run_on_remote_rq()") which conflicts
with 26176116d931 ("sched_ext: Count SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE in
the right spot") in for-6.15.

1  2 
kernel/sched/ext.c

index 90a66a2a43d5c42f96c0fe9d436597a3c14162e3,54edd0e2132a6525da3528db07c1857f8f89f74e..98d5f2f68f38c24d766698e6b803de428c299ffb
@@@ -2446,6 -2343,25 +2446,25 @@@ static bool task_can_run_on_remote_rq(s
  
        SCHED_WARN_ON(task_cpu(p) == cpu);
  
 -              if (trigger_error)
+       /*
+        * If @p has migration disabled, @p->cpus_ptr is updated to contain only
+        * the pinned CPU in migrate_disable_switch() while @p is being switched
+        * out. However, put_prev_task_scx() is called before @p->cpus_ptr is
+        * updated and thus another CPU may see @p on a DSQ inbetween leading to
+        * @p passing the below task_allowed_on_cpu() check while migration is
+        * disabled.
+        *
+        * Test the migration disabled state first as the race window is narrow
+        * and the BPF scheduler failing to check migration disabled state can
+        * easily be masked if task_allowed_on_cpu() is done first.
+        */
+       if (unlikely(is_migration_disabled(p))) {
++              if (enforce)
+                       scx_ops_error("SCX_DSQ_LOCAL[_ON] cannot move migration disabled %s[%d] from CPU %d to %d",
+                                     p->comm, p->pid, task_cpu(p), cpu);
+               return false;
+       }
        /*
         * We don't require the BPF scheduler to avoid dispatching to offline
         * CPUs mostly for convenience but also because CPUs can go offline
         * picked CPU is outside the allowed mask.
         */
        if (!task_allowed_on_cpu(p, cpu)) {
 -              if (trigger_error)
 +              if (enforce)
-                       scx_ops_error("SCX_DSQ_LOCAL[_ON] verdict target cpu %d not allowed for %s[%d]",
-                                     cpu_of(rq), p->comm, p->pid);
+                       scx_ops_error("SCX_DSQ_LOCAL[_ON] target CPU %d not allowed for %s[%d]",
+                                     cpu, p->comm, p->pid);
                return false;
        }
  
-       /*
-        * If @p has migration disabled, @p->cpus_ptr only contains its current
-        * CPU and the above task_allowed_on_cpu() test should have failed.
-        */
-       SCHED_WARN_ON(is_migration_disabled(p));
 -      if (!scx_rq_online(rq))
 +      if (!scx_rq_online(rq)) {
 +              if (enforce)
 +                      __scx_add_event(SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE, 1);
                return false;
 +      }
  
        return true;
  }