linux/kernel/locking
John Stultz 2d76226698 sched/locking: Add special p->blocked_on==PROXY_WAKING value for proxy return-migration
As we add functionality to proxy execution, we may migrate a
donor task to a runqueue where it can't run due to cpu affinity.
Thus, we must be careful to ensure we return-migrate the task
back to a cpu in its cpumask when it becomes unblocked.

Peter helpfully provided the following example with pictures:
"Suppose we have a ww_mutex cycle:

                  ,-+-* Mutex-1 <-.
        Task-A ---' |             | ,-- Task-B
                    `-> Mutex-2 *-+-'

Where Task-A holds Mutex-1 and tries to acquire Mutex-2, and
where Task-B holds Mutex-2 and tries to acquire Mutex-1.

Then the blocked_on->owner chain will go in circles.

        Task-A  -> Mutex-2
          ^          |
          |          v
        Mutex-1 <- Task-B

We need two things:

 - find_proxy_task() to stop iterating the circle;

 - the woken task to 'unblock' and run, such that it can
   back-off and re-try the transaction.

Now, the current code [without this patch] does:
        __clear_task_blocked_on();
        wake_q_add();

And surely clearing ->blocked_on is sufficient to break the
cycle.

Suppose it is Task-B that is made to back-off, then we have:

  Task-A -> Mutex-2 -> Task-B (no further blocked_on)

and it would attempt to run Task-B. Or worse, it could directly
pick Task-B and run it, without ever getting into
find_proxy_task().

Now, here is a problem because Task-B might not be runnable on
the CPU it is currently on; and because !task_is_blocked() we
don't get into the proxy paths, so nobody is going to fix this
up.

Ideally we would have dequeued Task-B alongside of clearing
->blocked_on, but alas, [the lock ordering prevents us from
getting the task_rq_lock() and] spoils things."

Thus we need more than just a binary concept of the task being
blocked on a mutex or not.

So allow setting blocked_on to PROXY_WAKING as a special value
which specifies the task is no longer blocked, but needs to
be evaluated for return migration *before* it can be run.

This will then be used in a later patch to handle proxy
return-migration.

Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://patch.msgid.link/20260324191337.1841376-7-jstultz@google.com
2026-04-03 14:23:40 +02:00
..
irqflag-debug.c
lock_events_list.h bpf_res_spin_lock 2025-03-30 13:06:27 -07:00
lock_events.c locking/debug: Fix debugfs API return value checks to use IS_ERR() 2023-10-03 10:11:25 +02:00
lock_events.h locking/qspinlock: Always evaluate lockevent* non-event parameter once 2024-03-21 20:45:17 +01:00
lockdep_internals.h locking/lockdep: Change 'static const' variables to enum values 2025-07-14 21:57:29 -07:00
lockdep_proc.c locking/lockdep: Avoid struct return in lock_stats() 2025-07-14 21:57:20 -07:00
lockdep_states.h
lockdep.c lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization 2025-07-14 21:57:29 -07:00
locktorture.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
Makefile locking/lockdep: Disable KASAN instrumentation of lockdep.c 2025-03-08 00:55:03 +01:00
mcs_spinlock.h locking: Allow obtaining result of arch_mcs_spin_lock_contended 2025-03-19 08:03:04 -07:00
mutex-debug.c locking: Add task::blocked_lock to serialize blocked_on state 2026-04-03 14:23:39 +02:00
mutex.c sched/locking: Add special p->blocked_on==PROXY_WAKING value for proxy return-migration 2026-04-03 14:23:40 +02:00
mutex.h locking: Add task::blocked_lock to serialize blocked_on state 2026-04-03 14:23:39 +02:00
osq_lock.c locking/osq_lock: Use atomic_try_cmpxchg_release() in osq_unlock() 2024-10-25 10:01:50 +02:00
percpu-rwsem.c locking/percpu-rwsem: add freezable alternative to down_read 2025-04-07 09:37:16 +02:00
qrwlock.c
qspinlock_paravirt.h locking/pvqspinlock: Convert fields of 'enum vcpu_state' to uppercase 2024-10-17 21:21:16 -07:00
qspinlock_stat.h
qspinlock.c locking: Move common qspinlock helpers to a private header 2025-03-19 08:02:29 -07:00
qspinlock.h locking: Move common qspinlock helpers to a private header 2025-03-19 08:02:29 -07:00
rtmutex_api.c locking/mutex: Redo __mutex_init() to reduce generated code size 2025-12-01 06:51:57 +01:00
rtmutex_common.h locking/local_lock: Introduce local_lock_is_locked(). 2025-09-29 09:42:35 +02:00
rtmutex.c locking/lock_events: Add locking events for rtmutex slow paths 2025-03-08 00:55:03 +01:00
rwbase_rt.c locking/mutex: Remove wakeups from under mutex::wait_lock 2024-10-14 12:52:40 +02:00
rwsem.c Significant patch series in this pull request: 2025-08-03 16:23:09 -07:00
semaphore.c hung_task: show the blocker task if the task is hung on semaphore 2025-05-11 17:54:08 -07:00
spinlock_debug.c locking/spinlock/debug: Fix data-race in do_raw_write_lock 2025-10-21 12:31:55 +02:00
spinlock_rt.c Scheduler changes for v6.13: 2024-11-19 14:16:06 -08:00
spinlock.c locking/spinlocks: Make __raw_* lock ops static 2024-10-07 09:28:35 +02:00
test-ww_mutex.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ww_mutex.h sched/locking: Add special p->blocked_on==PROXY_WAKING value for proxy return-migration 2026-04-03 14:23:40 +02:00
ww_rt_mutex.c locking/rtmutex: Avoid unconditional slowpath for DEBUG_RT_MUTEXES 2023-09-20 09:31:11 +02:00