[tip: locking/urgent] futex: Clean up the redundant exit/exec functions

"tip-bot2 for Thomas Gleixner" <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <178683298903.1542179.8748527561234052984.tip-bot2@tip-bot2>
The following commit has been merged into the locking/urgent branch of tip:

Commit-ID:     221b62e97811845340c888993ae049467399d2b5
Gitweb:        https://git.kernel.org/tip/221b62e97811845340c888993ae049467399d2b5
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Fri, 07 Aug 2026 17:07:17 +02:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Sun, 16 Aug 2026 00:16:32 +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 <[email protected]>
Reviewed-by: Kyle Zeng <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
---
 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 d01523d..22df492 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -856,7 +856,7 @@ static int exec_mmap(struct linux_binprm *bprm)
 	tsk = current;
 	old_mm = current->mm;
 	/* Clean up futexes and release the mm */
-	exec_mm_release(tsk, old_mm);
+	mm_exit_exec_release(tsk, old_mm);
 
 	ret = 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 *tsk)
 }
 
 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);
 
 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 *timeout,
 			    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_struct *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 *);
 
 #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 = current->mm;
 
-	exit_mm_release(current, mm);
+	mm_exit_exec_release(current, mm);
 	if (!mm)
 		return;
 
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, struct mm_struct *mm)
 		complete_vfork_done(tsk);
 }
 
-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);
 }
 
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 *tsk)
 	mutex_unlock(&tsk->futex.exit_mutex);
 }
 
-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 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().
+ */
+void futex_exit_exec_release(struct task_struct *tsk)
 {
 	futex_cleanup_begin(tsk);
 	futex_cleanup(tsk);
 	futex_cleanup_end(tsk);
 }
 
-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.
  */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.