[PATCH 3/8] mm: take a lock-free exec_update_seq fast path in mm_access()

From: Christian Brauner

Date: Mon May 25 2026 - 03:27:57 EST


mm_access() takes exec_update_lock for read only to check
ptrace_may_access() against stable credentials before grabbing the target
mm. Convert it to exec_update_read_begin_or_lock(): the common case
resolves and access-checks the mm with no lock; a concurrent exec()/TSYNC
falls back to exec_update_lock. The shared resolve/check logic moves to
__mm_access(), and the speculative mm reference is dropped before retry.

Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
kernel/fork.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index 377125eff8a9..250a7e1125e6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1394,23 +1394,38 @@ static bool may_access_mm(struct mm_struct *mm, struct task_struct *task, unsign
return false;
}

+static struct mm_struct *__mm_access(struct task_struct *task, unsigned int mode)
+{
+ struct mm_struct *mm = get_task_mm(task);
+
+ if (!mm)
+ return ERR_PTR(-ESRCH);
+ if (!may_access_mm(mm, task, mode)) {
+ mmput(mm);
+ return ERR_PTR(-EACCES);
+ }
+ return mm;
+}
+
struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
{
+ struct signal_struct *sig = task->signal;
struct mm_struct *mm;
+ unsigned int seq = 0;
int err;

- err = down_read_killable(&task->signal->exec_update_lock);
+retry:
+ err = exec_update_read_begin_or_killable(sig, &seq);
if (err)
return ERR_PTR(err);
-
- mm = get_task_mm(task);
- if (!mm) {
- mm = ERR_PTR(-ESRCH);
- } else if (!may_access_mm(mm, task, mode)) {
- mmput(mm);
- mm = ERR_PTR(-EACCES);
- }
- up_read(&task->signal->exec_update_lock);
+ mm = __mm_access(task, mode);
+ if (exec_update_read_needs_retry(sig, seq)) {
+ if (!IS_ERR(mm))
+ mmput(mm);
+ seq = 1;
+ goto retry;
+ }
+ exec_update_read_done(sig, seq);

return mm;
}
--
2.47.3


--j3ezp33mpunnwnqz
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment;
filename="0004-pidfd-take-a-lock-free-exec_update_seq-fast-path-in-.patch"