From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from canpmsgout09.his.huawei.com (canpmsgout09.his.huawei.com [113.46.200.224]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D01925B0B7 for ; Mon, 20 Jul 2026 02:40:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.224 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784515232; cv=none; b=PLp9d8z7r1QsB8HN077a31e1Z4qzog4A1muOkQYsKJOkVAn78FELiUWWdK8+bqQUnMgqPE629sAop67T8RFrNc/L14QDx3RkDAcVFLOdhGOiLwPeNvMj/kK8jsFFc7WHJZlFyUjMKo5YdqehTeCkYBJZSq3t66HxzGJRLFrpoGg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784515232; c=relaxed/simple; bh=p/SLZbD6Kg1z3/nY3uKg1uHRC6xY1kCnwHataUueucw=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=jOggK+O74YnZGduiUCWPgPCvqKnZunvbctAW8sxHc++1PN+bICm4/c5jWrfIEyb1q73RGFd1pSB5BT7my7aDNgb0EE+a4e95y1IWxcsD8Ka8mTgjx6wHSRrGN2wgkvc2Q5wxzlO5ejcWeH6NTuwttrpRINFBDZicnEJWSrPKcc0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=e8yylb29; arc=none smtp.client-ip=113.46.200.224 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="e8yylb29" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=uHa/Jh7+l14eUV7r14r0IkjZ8xPyVcvBdtiTGG20SLU=; b=e8yylb2913Tsba19IJK9jUTb6ar8xJEHyZxBKkl4o1i2OaRcNJKIJ+WTVZ3LnNU/nEnQ9moYS cJa0NloNHHw36w4mSO/1WaRdzeZG8FZY9xrDP2whCZOXtRh5eWMvs/YRjON+QarCc7sReO5c8AB KeXOi6O30qkPC4M7fnteDK4= Received: from mail.maildlp.com (unknown [172.19.163.127]) by canpmsgout09.his.huawei.com (SkyGuard) with ESMTPS id 4h3Pdc0WSwz1cyVQ; Mon, 20 Jul 2026 10:31:00 +0800 (CST) Received: from dggpemr500006.china.huawei.com (unknown [7.185.36.185]) by mail.maildlp.com (Postfix) with ESMTPS id E274D402AB; Mon, 20 Jul 2026 10:40:19 +0800 (CST) Received: from [100.103.109.15] (100.103.109.15) by dggpemr500006.china.huawei.com (7.185.36.185) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Mon, 20 Jul 2026 10:40:19 +0800 Message-ID: <89dce8bf-8aec-4b3a-a588-f3dab35e8977@huawei.com> Date: Mon, 20 Jul 2026 10:40:03 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 1/2] futex/requeue: Fix rtmutex schedule preparation for requeue PI To: Sebastian Andrzej Siewior CC: , , , , , , , References: <20260717084922.4153317-1-yaokai34@huawei.com> <20260717084922.4153317-2-yaokai34@huawei.com> <20260717085548.slwReTBC@linutronix.de> Content-Language: en-US From: Yao Kai In-Reply-To: <20260717085548.slwReTBC@linutronix.de> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To dggpemr500006.china.huawei.com (7.185.36.185) On 7/17/2026 4:55 PM, Sebastian Andrzej Siewior wrote: > On 2026-07-17 16:49:21 [+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 and submits pending work before the waiter >> is enqueued. 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 waiter consequently enters rt_mutex_schedule() with >> current->sched_rt_mutex clear. Its block plug remains unflushed, and >> workqueue or io-wq users are not notified that the worker is going to >> sleep. > > This has nothing to do with, does it? It is just usually the lock is > acquired and it is not blocked on. Do you have testcase for this or is > this just audit? > I have a test but it only triggers the warning. The concern about calling rt_mutex_pre_schedule() after the proxy waiter has been enqueued came from audit. A generic PREEMPT_RT path could be: rt_mutex_pre_schedule() sched_submit_work() blk_flush_plug() __blk_flush_plug() flush_plug_callbacks() drbd_unplug() spin_lock_irq() rtlock_slowlock() task_blocks_on_rt_mutex() current->pi_blocked_on = waiter However, I could not find a path for FUTEX_WAIT_REQUEUE_PI to enter with a live current->plug or worker flags, so this recursion is not reachable from this syscall. >> rt_mutex_pre_schedule() cannot be used directly. Calling it before q is >> published would set current->sched_rt_mutex while futex_do_wait() can still >> call regular schedule(). Calling it after DONE would flush the block plug >> after current->pi_blocked_on is installed, which can recurse into rtmutex >> waiter setup. >> >> Split the preparation instead. Flush the plug before futex_wait_setup() >> publishes q. After futex_requeue_pi_wakeup_sync() returns DONE, enter the >> rtmutex scheduling state and notify workqueue and io-wq users without >> flushing the plug again. Split sched_submit_work() to support this ordering >> and leave the scheduling state after the waiter has acquired the lock or >> has been removed. >> >> Fixes: d14f9e930b90 ("locking/rtmutex: Use rt_mutex specific scheduler helpers") >> Cc: stable@vger.kernel.org >> Signed-off-by: Yao Kai > > what about the following? This might compile but lacks all kind of testing. > > diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c > index 79823ad136830..42a04e6e774c4 100644 > --- a/kernel/futex/requeue.c > +++ b/kernel/futex/requeue.c > @@ -865,7 +865,9 @@ 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; > + rt_mutex_pre_schedule(); > ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); > + rt_mutex_post_schedule(); > > /* > * See futex_unlock_pi()'s cleanup: comment. This also fixes the warning in my test. I would keep rt_mutex_post_schedule() after the proxy waiter cleanup, as futex_lock_pi() does: diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c index 79823ad13683..41ffc795d12c 100644 --- a/kernel/futex/requeue.c +++ b/kernel/futex/requeue.c @@ -865,6 +865,7 @@ 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; + rt_mutex_pre_schedule(); ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); /* @@ -875,6 +876,7 @@ int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, futex_q_lockptr_lock(&q); debug_rt_mutex_free_waiter(&rt_waiter); + rt_mutex_post_schedule(); /* * Fixup the pi_state owner and possibly acquire the lock if we * haven't already. Thanks, Yao