All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Yao Kai <yaokai34@huawei.com>
Cc: linux-kernel@vger.kernel.org, tglx@kernel.org, mingo@redhat.com,
	dvhart@infradead.org, dave@stgolabs.net, andrealmeid@igalia.com,
	bigeasy@linutronix.de, liuyongqiang13@huawei.com
Subject: Re: [PATCH v2 1/2] futex/requeue: Fix rtmutex schedule preparation for requeue PI
Date: Tue, 4 Aug 2026 14:21:02 +0200	[thread overview]
Message-ID: <20260804122102.GI776954@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20260722085140.1949077-2-yaokai34@huawei.com>

On Wed, Jul 22, 2026 at 04:51:39PM +0800, Yao Kai wrote:
> A waiter requeued onto a PI futex can reach rt_mutex_wait_proxy_lock()
> without rtmutex schedule preparation:
> 
>   WARNING: CPU: 0 PID: 293 at kernel/sched/core.c:7606
>   RIP: rt_mutex_schedule+0x43/0x50
>   Call Trace:
>    rt_mutex_slowlock_block.constprop.0+0x5b/0x320
>    rt_mutex_wait_proxy_lock+0x3e/0x80
>    futex_wait_requeue_pi+0x3ba/0x590
>    do_futex+0x171/0x1f0
> 
> rt_mutex_schedule() requires current->sched_rt_mutex to be set. Normally,
> rt_mutex_pre_schedule() sets it before an rtmutex waiter can schedule. With
> requeue PI, another task can enqueue the waiter after its futex_q becomes
> visible:
> 
>         waiter                          requeue task
>         ------                          ------------
> futex_wait_requeue_pi()
>   futex_wait_setup()
>     futex_queue(&q)
>                                         futex_requeue()
>                                           rt_mutex_start_proxy_lock()
>                                             enqueue rt_waiter
>                                             install pi_blocked_on
>                                           requeue_futex()
>                                             plist_del(&q->list)
>   futex_do_wait()
>     plist_node_empty(&q->list)
>     skip schedule()
>                                             plist_add(&q->list)
>                                           futex_requeue_pi_complete()
>                                             IN_PROGRESS -> DONE
>   futex_requeue_pi_wakeup_sync() // DONE
>   rt_mutex_wait_proxy_lock()
>     rt_mutex_schedule()
> 
> futex_do_wait() mistakes the temporary removal for a wakeup and skips
> schedule(). The proxy waiter can nevertheless remain blocked on the target
> rtmutex and subsequently enter rt_mutex_schedule() with
> current->sched_rt_mutex clear.
> 
> Call rt_mutex_pre_schedule() and rt_mutex_post_schedule() directly around
> rt_mutex_wait_proxy_lock() so this second blocking point has the required
> scheduler preparation.
> 
> Fixes: d14f9e930b90 ("locking/rtmutex: Use rt_mutex specific scheduler helpers")
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: stable@vger.kernel.org
> Signed-off-by: Yao Kai <yaokai34@huawei.com>
> ---
>  kernel/futex/requeue.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c
> index 79823ad13683..f7889fb2fce4 100644
> --- a/kernel/futex/requeue.c
> +++ b/kernel/futex/requeue.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later
>  
>  #include <linux/plist.h>
> +#include <linux/sched/rt.h>
>  #include <linux/sched/signal.h>
>  
>  #include "futex.h"
> @@ -865,7 +866,14 @@ int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
>  	case Q_REQUEUE_PI_DONE:
>  		/* Requeue completed. Current is 'pi_blocked_on' the rtmutex */
>  		pi_mutex = &q.pi_state->pi_mutex;
> +		/*
> +		 * Requeue temporarily removes q from the hash bucket, so
> +		 * futex_do_wait() may skip schedule() even though the proxy
> +		 * waiter still has to block on the rtmutex.
> +		 */
> +		rt_mutex_pre_schedule();
>  		ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter);
> +		rt_mutex_post_schedule();

As per always, I'm totally confused about everything. I mean, futexes
suck, but requeue sucks worse.

So the purpose of rt_mutex_pre_schedule() was to avoid the double waiter
enqueue for rt_mutex on RT, where sched_submit_work() will hit a
spinlock-nee-rtlock.

So rt_mutex_pre_schedule() must happen before the rt_mutex is added as a
waiter. However, AFAICT we're already a waiter at the above spot, no? So
this cannot be right.

The changelogs doesn't at all explain why this is correct. Please help?

  reply	other threads:[~2026-08-04 12:21 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22  8:51 [PATCH v2 0/2] futex/requeue: Fix requeue PI races Yao Kai
2026-07-22  8:51 ` [PATCH v2 1/2] futex/requeue: Fix rtmutex schedule preparation for requeue PI Yao Kai
2026-08-04 12:21   ` Peter Zijlstra [this message]
2026-08-05  8:00     ` Yao Kai
2026-07-22  8:51 ` [PATCH v2 2/2] futex/requeue: Prevent rcuwait use-after-free during " Yao Kai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260804122102.GI776954@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=andrealmeid@igalia.com \
    --cc=bigeasy@linutronix.de \
    --cc=dave@stgolabs.net \
    --cc=dvhart@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuyongqiang13@huawei.com \
    --cc=mingo@redhat.com \
    --cc=tglx@kernel.org \
    --cc=yaokai34@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.