Re: [RFC PATCH v2 2/2] sched/wait: Clarify WF_SYNC wakeup semantics
From: Peter Zijlstra
Date: Fri Sep 18 2026 - 07:55:16 EST
On Thu, Sep 17, 2026 at 01:43:25PM -0700, Shubhang Kaushik (Ampere) wrote:
> The synchronous waitqueue wakeup comments state that the wakee will not
> be migrated to another CPU. This is not guaranteed by the current
> scheduler wakeup path.
>
> The synchronous helpers pass WF_SYNC to waitqueue wake functions. The
> default wake function forwards it to the scheduler, where fair-class
> tasks can use it as a wakeup-placement and preemption hint.
>
> Correct the API comments to describe this behavior and remove the
> incorrect no-migration guarantee.
>
> Signed-off-by: Shubhang Kaushik (Ampere) <sh@xxxxxxxxxx>
> ---
> kernel/sched/wait.c | 30 ++++++++++++++++--------------
> 1 file changed, 16 insertions(+), 14 deletions(-)
>
> diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c
> index d033f600f48c6fc3a0a088ea5d9f6ed95ec4c86e..ac1d260a6a37fc35b934079706819b79e20df4ba 100644
> --- a/kernel/sched/wait.c
> +++ b/kernel/sched/wait.c
> @@ -174,15 +174,16 @@ EXPORT_SYMBOL_GPL(__wake_up_locked_key);
> * @mode: which threads
> * @key: opaque value to be passed to wakeup targets
> *
> - * The sync wakeup differs that the waker knows that it will schedule
> - * away soon, so while the target thread will be woken up, it will not
> - * be migrated to another CPU - ie. the two threads are 'synchronized'
> - * with each other. This can prevent needless bouncing between CPUs.
> + * The caller expects the waker to schedule away soon. This helper passes
> + * WF_SYNC to waitqueue wake functions. The default wake function forwards
> + * it to the scheduler.
> *
> - * On UP it can prevent extra preemption.
> + * For fair-class tasks, WF_SYNC is a wakeup-placement and preemption
> + * hint. It does not guarantee that the wakee will run on the waker CPU
> + * or avoid migration. On UP, this may avoid an unnecessary preemption.
> *
> - * If this function wakes up a task, it executes a full memory barrier before
> - * accessing the task state.
> + * If this function wakes up a task, it executes a full memory barrier
> + * before accessing the task state.
> */
> void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode,
> void *key)
> @@ -200,15 +201,16 @@ EXPORT_SYMBOL_GPL(__wake_up_sync_key);
> * @mode: which threads
> * @key: opaque value to be passed to wakeup targets
> *
> - * The sync wakeup differs in that the waker knows that it will schedule
> - * away soon, so while the target thread will be woken up, it will not
> - * be migrated to another CPU - ie. the two threads are 'synchronized'
> - * with each other. This can prevent needless bouncing between CPUs.
> + * The caller expects the waker to schedule away soon. This helper passes
> + * WF_SYNC to waitqueue wake functions. The default wake function forwards
> + * it to the scheduler
> *
> - * On UP it can prevent extra preemption.
> + * For fair-class tasks, WF_SYNC is a wakeup-placement and preemption
> + * hint. It does not guarantee that the wakee will run on the waker CPU
> + * or avoid migration. On UP, this may avoid an unnecessary preemption.
> *
> - * If this function wakes up a task, it executes a full memory barrier before
> - * accessing the task state.
> + * If this function wakes up a task, it executes a full memory barrier
> + * before accessing the task state.
> */
> void __wake_up_locked_sync_key(struct wait_queue_head *wq_head,
> unsigned int mode, void *key)
Does it make sense to have one of those function refer to the other and
de-duplicate all that? Also, how relevant is the UP comment? I don't
think anybody much still cares about UP.