summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Righi <arighi@nvidia.com>2026-09-15 20:41:01 +0200
committerPeter Zijlstra <peterz@infradead.org>2026-09-18 12:19:43 +0200
commitfe3c73d7bc769e7afc252f867a3421fe168b898d (patch)
treee3ea58cbeeca2df1d4e1bfc7239469c929a4d04a
parentfd73f4a6659897191fa0d40695fe370925dd3780 (diff)
downloadlinux-stable-fe3c73d7bc769e7afc252f867a3421fe168b898d.tar.gz
linux-stable-fe3c73d7bc769e7afc252f867a3421fe168b898d.zip
sched/core: Avoid false migration warning for proxy donors
Proxy execution can move a blocked donor's scheduling context to the lock owner's CPU even when the donor is migration-disabled. The donor does not execute there, and its original execution CPU remains recorded in wake_cpu. set_task_cpu() warns unconditionally for migration-disabled tasks, so a subsequent proxy migration or the wakeup path returning the donor home triggers a false positive: moving a blocked scheduling context does not violate the migration-disabled execution context. For example, creating a mutex owner on CPU1 and a migration-disabled waiter on CPU0 can trigger the following warning: proxy_migrate_repro: donor blocking on CPU0 with migration disabled proxy_migrate_repro: donor moved from CPU0 to CPU1 WARNING: kernel/sched/core.c:3389 at set_task_cpu+0x1d3/0x280 ... Call Trace: try_to_wake_up+0x43f/0x780 __mutex_unlock_slowpath+0x330/0x540 owner_fn+0x9f/0xc0 [proxy_migrate_repro] ... proxy_migrate_repro: donor woke on CPU0, task_cpu=0 proxy_migrate_repro: completed Exclude blocked proxy donors from the warning. The proxy wakeup path restores an executable placement before clearing the blocked state. Fixes: b049b81bdff6 ("sched: Handle blocked-waiter migration (and return migration)") Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: John Stultz <jstultz@google.com> Link: https://patch.msgid.link/20260915184101.2621252-1-arighi@nvidia.com
-rw-r--r--kernel/sched/core.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 7885ff76e..0b846a13c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3351,6 +3351,8 @@ void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
{
unsigned int state = READ_ONCE(p->__state);
+ bool proxy_migrated = sched_proxy_exec() && p->is_blocked &&
+ task_cpu(p) != p->wake_cpu;
/*
* We should never call set_task_cpu() on a blocked task,
@@ -3386,7 +3388,12 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
*/
WARN_ON_ONCE(!cpu_online(new_cpu));
- WARN_ON_ONCE(is_migration_disabled(p));
+ /*
+ * Proxy execution can move a blocked task's scheduling context to any
+ * CPU without moving its migration-disabled execution context. The
+ * wakeup path will return the task to a CPU where it can execute.
+ */
+ WARN_ON_ONCE(is_migration_disabled(p) && !proxy_migrated);
trace_sched_migrate_task(p, new_cpu);