From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 670C02D662F for ; Mon, 24 Aug 2026 14:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787580494; cv=none; b=cOmoAFp2i+Y+dVu7wk+ftu2BcHc6vWiiWspKwePM+UyECun3yfJZ9EfxnvXeC0yPBEEUfKUA2f0AoQbJleJrhXDsmcxadQqSbiTuzghZQ5ZkLVtjYevHA6ze1FyYJ0G+/vULoKQ8fQenKOr2UrEN1rL5SO+LN8zGnLL19lAI/6E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787580494; c=relaxed/simple; bh=uKPsmlGdTCVEXMWzRkcnbIk6PiYe9Rn8NouHvpuxaWQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=K0LDuE4Ki3SP2vsaxPGK42eyr7v0DqKw7jFdcOqQrDS/akq8TKiJbOeYNqnRcc82hcYG4dapeV76Gpiy3k7lP/a3meOQB7qk1J+iFBTzKG/D4A1WUPkJ2rDknPqg5TF8ewi+cuj23R1b1ztv68BG4WL5XNwaKfhHSwq6DS2t588= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NqMsN7tX; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wSBZxOr3; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NqMsN7tX"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wSBZxOr3" Date: Mon, 24 Aug 2026 16:08:09 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1787580491; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tsUtbKJkBjsFfz1FJ3xKHtl4+ok4HvlL07Qju+u1J/M=; b=NqMsN7tXlzwqjLpULXVn1zi/X/Py3lXucReV2OmENb2djn7TgmtGLo2Lgops0n1C9+jSyi BmcOc5T1jNcXxVIcCgQTNsgrgugUCTNn9jLl2AFooHYZCn0f+Wc9lsUCvixKT4MpxTykeF SaWFaJCtyKuXDtl8pf8ccnyOU5m76edX1d3UVGaF3tEtJ8jbJvg9GeBk6LBFsZu/dLogPt Pof/W00bkbFl4DaUXO060LNnbEQLKhbT0s0TgkYP+ZTZmgW75XI7VxTUYSXvchD2/jGAep X/xbQplbni4ATyhoacx0gICI+f4gqAB+oU2Xm0lrLPYWKYPrNfs6QExFz9XUHw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1787580491; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tsUtbKJkBjsFfz1FJ3xKHtl4+ok4HvlL07Qju+u1J/M=; b=wSBZxOr3CDNBE2AmJKmjdL2HAAoYpjUKLYkvBj+bxGNVzlDDuaTsnLsRTx0GM+eysOWaA/ r2tUnVMS21FHj+CQ== From: Sebastian Andrzej Siewior To: Peter Zijlstra Cc: Yao Kai , linux-kernel@vger.kernel.org, tglx@kernel.org, mingo@redhat.com, dvhart@infradead.org, dave@stgolabs.net, andrealmeid@igalia.com, liuyongqiang13@huawei.com, Crystal Wood Subject: Re: [PATCH v2 1/2] futex/requeue: Fix rtmutex schedule preparation for requeue PI Message-ID: <20260824140809.eJxsIRHn@linutronix.de> References: <20260722085140.1949077-1-yaokai34@huawei.com> <20260722085140.1949077-2-yaokai34@huawei.com> <20260804122102.GI776954@noisy.programming.kicks-ass.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: <20260804122102.GI776954@noisy.programming.kicks-ass.net> On 2026-08-04 14:21:02 [+0200], Peter Zijlstra wrote: > > @@ -865,7 +866,14 @@ int futex_wait_requeue_pi(u32 __user *uaddr, unsig= ned int flags, > > case Q_REQUEUE_PI_DONE: > > /* Requeue completed. Current is 'pi_blocked_on' the rtmutex */ > > pi_mutex =3D &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 =3D rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); > > + rt_mutex_post_schedule(); >=20 =E2=80=A6 > 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. >=20 > 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. Urgh. So I missed this part entirely while reading it. Isn't the usage of this in futex_lock_pi() just to keep the assert quiet? We do add a waiter there (futex_lock_pi()) and this (rt_mutex_pre_schedule()) must be done before a waiter is enqueued so we can acquire the lock (mutex) during the blk_flush_plug() which is in general part of schedule(). While doing all this, we moved the flush outside for mutex_t locking (mutex_lock() and others like it) and use rt_mutex_schedule() instead of schedule(). We do rt_mutex_pre_schedule() to flush the possible plug to avoid a deadlock in case we didn't flush it and someone waits for it. But need to do it before we add a waiter because we can be only have on one pi_waiter. spinlock_t doesn't flush it so we use schedule_rtlock() there instead because as per definition this kind of lock can't have any dependency so we don't flush the plug. Since the futex's rt_mutex usage matches more the mutex we ended up with rt_mutex_pre_schedule() + rt_mutex_schedule() around the wait schedule. blk_flush_plug() is not preserved across syscalls boundaries, there is usually blk_start_plug() followed by blk_finish_plug(). So the futex code shouldn't have the need to flush it at all because there shouldn't be any. I suppose for futex's usage it should be enough to simple have a dummy to skip the assert and not flush the plug at all. Otherwise we would have to flush the possible plug before futex_wait_setup() (since starting here the requeue code could act) and need to clear task_struct::sched_rt_mutex before futex_do_wait() again because it's schedule() usage will trigger another assert. And then we need something for rt_mutex_wait_proxy_lock(). So maybe, we have something to satisfy the assert without plug flush for futex/pi/requeue. > The changelogs doesn't at all explain why this is correct. Please help? I updated it for other reasons. Probably not what you have expected. Maybe the above is better reasoning but then we might want a different solution=E2=80=A6 Sebastian