From nobody Tue Sep 29 09:08:37 2026 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 534AB35C1A6; Mon, 10 Aug 2026 08:09:05 +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=1786349346; cv=none; b=OhvHMnoBL90X8ngMNbwVa4yK7XzYh4q6UblEoZSV76f6nfZIV/Z6gXDiMepqNSVTqLcJRpns3CL30QJRieG1i2TPRr4mlzjc8bSIr2hff5viQZTxm+1KINYOTwoAusifoVdvshIydVVZIqLX8mjxVp0LNq3BNat0IkB0Yk6AUgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786349346; c=relaxed/simple; bh=58ojgCsoAU2NCxhjT7d763uxKyXRl7PjxqiGtW2BlZs=; h=Date:From:To:Subject:Cc:MIME-Version:Message-ID:Content-Type; b=OsbstK9Gsv3Pz8b9TKKb89O58sTpWmfVT+mLNUU7Oe43oDfbxECq+KiDcZjLSLX2VBubWc9isnj69kQJZ1MwikfRXSixECoihi4EV1cBAa9NbHohAbBI63Xwy+Z9NkIaYVgy5ZuRvyxR3PWykhm0j5biyUx/iRIraEGSJfynwGA= 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=k8yM1PHe; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=8x+CKcPX; 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="k8yM1PHe"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="8x+CKcPX" Date: Mon, 10 Aug 2026 08:09:01 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1786349343; h=from:from:sender:sender:reply-to: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; bh=hBArIfP1U9lm99kcAryf8bETb5+mS4a6UIz4YgMaQb0=; b=k8yM1PHe/HZJbRRhKTYhw+zt/pkfQvRzzFo5Y3qG4DPvf/XQLreKoztLQl6DWEPOjWQKnE OU3O9M6r8yQuL3dafjLWdzhIiVR/rJYI/KVr66mwNgJlg2U+9duqwRtPSKkCyrwgML0+MC pb4/rCiC4zvOMiB/iiGH3qQP2LyC+Ywm/J94jT3nUGrmWR9mjUUqTTjMO/9HxxiZlg+VYH y7eDziOLMePc+pi+Y5i3mntj5ELqLDzysDh6PJ4XsdGzdu3c9xi3EtYL95NkECO8MufkFx 33Kj+CaJo7IKwZFZpNTYT86Z1mGaTZGmVzE6AfdXeYeGwg/0x3vzCZxXn/LJpA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1786349343; h=from:from:sender:sender:reply-to: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; bh=hBArIfP1U9lm99kcAryf8bETb5+mS4a6UIz4YgMaQb0=; b=8x+CKcPXH5BKKprJqftPAUX3+XCUw0yfp5kLbR9SM+Tn0aoMILgZPi5teKW3vBkPYZdn5K 0N/9RFAClIyACjAw== From: "tip-bot2 for Thomas Gleixner" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/urgent] futex: Clean up the redundant exit/exec functions Cc: Thomas Gleixner , Kyle Zeng , Peter Zijlstra , x86@kernel.org, linux-kernel@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178634934156.442315.873840180246375983.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the locking/urgent branch of tip: Commit-ID: 36a48625df6d91302438fb9f49a54e391fd9b63b Gitweb: https://git.kernel.org/tip/36a48625df6d91302438fb9f49a54e391= fd9b63b Author: Thomas Gleixner AuthorDate: Fri, 07 Aug 2026 17:07:17 +02:00 Committer: Thomas Gleixner CommitterDate: Mon, 10 Aug 2026 10:07:53 +02:00 futex: Clean up the redundant exit/exec functions futex_exit_release() and futex_exec_release() are identical now. That means also exit_mm_release() and exec_mm_release() are identical. Consolidate the whole lot and remove the redundant copies. Signed-off-by: Thomas Gleixner Reviewed-by: Kyle Zeng Acked-by: Peter Zijlstra --- fs/exec.c | 2 +- include/linux/futex.h | 6 ++---- include/linux/sched/mm.h | 10 ++++++---- kernel/exit.c | 2 +- kernel/fork.c | 10 ++-------- kernel/futex/core.c | 37 +++++++++++++++++-------------------- 6 files changed, 29 insertions(+), 38 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 8a91c58..74d30a3 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -856,7 +856,7 @@ static int exec_mmap(struct linux_binprm *bprm) tsk =3D current; old_mm =3D current->mm; /* Clean up futexes and release the mm */ - exec_mm_release(tsk, old_mm); + mm_exit_exec_release(tsk, old_mm); =20 ret =3D down_write_killable(&tsk->signal->exec_update_lock); if (ret) diff --git a/include/linux/futex.h b/include/linux/futex.h index 51d5faa..18ed18d 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -71,8 +71,7 @@ static inline void futex_init_task(struct task_struct *ts= k) } =20 void futex_exit_recursive(struct task_struct *tsk); -void futex_exit_release(struct task_struct *tsk); -void futex_exec_release(struct task_struct *tsk); +void futex_exit_exec_release(struct task_struct *tsk); void futex_exec_done(struct task_struct *tsk); =20 long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, @@ -90,8 +89,7 @@ static inline int futex_hash_free(struct mm_struct *mm) {= return 0; } #else /* CONFIG_FUTEX */ static inline void futex_init_task(struct task_struct *tsk) { } static inline void futex_exit_recursive(struct task_struct *tsk) { } -static inline void futex_exit_release(struct task_struct *tsk) { } -static inline void futex_exec_release(struct task_struct *tsk) { } +static inline void futex_exit_exec_release(struct task_struct *tsk) { } static inline void futex_exec_done(struct task_struct *tsk) { } static inline long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *t= imeout, u32 __user *uaddr2, u32 val2, u32 val3) diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 95d0040..7fe7dfd 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -155,10 +155,12 @@ extern struct mm_struct *get_task_mm(struct task_stru= ct *task); * succeeds. */ extern struct mm_struct *mm_access(struct task_struct *task, unsigned int = mode); -/* Remove the current tasks stale references to the old mm_struct on exit(= ) */ -extern void exit_mm_release(struct task_struct *, struct mm_struct *); -/* Remove the current tasks stale references to the old mm_struct on exec(= ) */ -extern void exec_mm_release(struct task_struct *, struct mm_struct *); + +/* + * Remove the current tasks stale references to the old mm_struct on exit(= ) and + * exec(). Cleans up futexes as well. + */ +extern void mm_exit_exec_release(struct task_struct *, struct mm_struct *); =20 #ifdef CONFIG_MEMCG extern void mm_update_next_owner(struct mm_struct *mm); diff --git a/kernel/exit.c b/kernel/exit.c index 2c0b1c0..adf93b9 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -582,7 +582,7 @@ static void exit_mm(void) { struct mm_struct *mm =3D current->mm; =20 - exit_mm_release(current, mm); + mm_exit_exec_release(current, mm); if (!mm) return; =20 diff --git a/kernel/fork.c b/kernel/fork.c index f0e2e13..7c6918b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1502,15 +1502,9 @@ static void mm_release(struct task_struct *tsk, stru= ct mm_struct *mm) complete_vfork_done(tsk); } =20 -void exit_mm_release(struct task_struct *tsk, struct mm_struct *mm) +void mm_exit_exec_release(struct task_struct *tsk, struct mm_struct *mm) { - futex_exit_release(tsk); - mm_release(tsk, mm); -} - -void exec_mm_release(struct task_struct *tsk, struct mm_struct *mm) -{ - futex_exec_release(tsk); + futex_exit_exec_release(tsk); mm_release(tsk, mm); } =20 diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 3c1562d..2d1dbde 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -1537,32 +1537,29 @@ static void futex_cleanup_end(struct task_struct *t= sk) mutex_unlock(&tsk->futex.exit_mutex); } =20 -void futex_exit_release(struct task_struct *tsk) +/* + * Invoked from mm_exit_exec_release() to cleanup the robust lists and pi = state + * of the outgoing task. + * + * exec() makes it interesting for futexes because the TID of the task sta= ys the + * same, but from a futex perspective the task has to be treated like an e= xiting + * task. This is especially important for the sanity check for private fut= exes + * in attach_to_pi_owner() which compares the owner's mm with the waiter's= mm. + * + * That check would give the wrong answer if futex_cleanup_end() would + * set the state to FUTEX_STATE_OK as long as the task still has the old + * mm. + * + * After the task has switched to the new mm it sets it to + * FUTEX_STATE_OK again in futex_exec_done(). + */ +void futex_exit_exec_release(struct task_struct *tsk) { futex_cleanup_begin(tsk); futex_cleanup(tsk); futex_cleanup_end(tsk); } =20 -void futex_exec_release(struct task_struct *tsk) -{ - /* - * exec() makes it interesting for futexes because the TID of the task - * stays the same, but from a futex perspective the task has to be - * treated like an exiting task. This is especially important for the - * sanity check for private futexes in attach_to_pi_owner() which - * compares the owner's mm with the waiter's mm. - * - * That check would give the wrong answer if futex_cleanup_end() would - * set the state to FUTEX_STATE_OK as long as the task still has the old - * mm. - * - * After the task has switched to the new mm it sets it to - * FUTEX_STATE_OK again in futex_exec_done(). - */ - futex_exit_release(tsk); -} - /* * exec() has switched to the new mm. Futex operations are safe again. */