From: Andrew Morton <akpm@linux-foundation.org>
To: mm-commits@vger.kernel.org,surenb@google.com,akpm@linux-foundation.org
Subject: + mm-use-vma_start_write_killable-in-mm-syscalls.patch added to mm-new branch
Date: Fri, 27 Mar 2026 16:12:50 -0700 [thread overview]
Message-ID: <20260327231252.B386EC19423@smtp.kernel.org> (raw)
The patch titled
Subject: mm: use vma_start_write_killable() in mm syscalls
has been added to the -mm mm-new branch. Its filename is
mm-use-vma_start_write_killable-in-mm-syscalls.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-use-vma_start_write_killable-in-mm-syscalls.patch
This patch will later appear in the mm-new branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Note, mm-new is a provisional staging ground for work-in-progress
patches, and acceptance into mm-new is a notification for others take
notice and to finish up reviews. Please do not hesitate to respond to
review feedback and post updated versions to replace or incrementally
fixup patches in mm-new.
The mm-new branch of mm.git is not included in linux-next
If a few days of testing in mm-new is successful, the patch will me moved
into mm.git's mm-unstable branch, which is included in linux-next
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via various
branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there most days
------------------------------------------------------
From: Suren Baghdasaryan <surenb@google.com>
Subject: mm: use vma_start_write_killable() in mm syscalls
Date: Fri, 27 Mar 2026 13:54:53 -0700
Replace vma_start_write() with vma_start_write_killable() in syscalls,
improving reaction time to the kill signal.
In a number of places we now lock VMA earlier than before to avoid doing
work and undoing it later if a fatal signal is pending. This is safe
because the moves are happening within sections where we already hold the
mmap_write_lock, so the moves do not change the locking order relative to
other kernel locks.
Link: https://lkml.kernel.org/r/20260327205457.604224-3-surenb@google.com
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Suggested-by: Matthew Wilcox <willy@infradead.org>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Jann Horn <jannh@google.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
mm/madvise.c | 13 ++++++++++---
mm/memory.c | 2 ++
mm/mempolicy.c | 11 +++++++++--
mm/mlock.c | 30 ++++++++++++++++++++++++------
mm/mprotect.c | 25 +++++++++++++++++--------
mm/mremap.c | 8 +++++---
mm/mseal.c | 24 +++++++++++++++++++-----
7 files changed, 86 insertions(+), 27 deletions(-)
--- a/mm/madvise.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/madvise.c
@@ -172,10 +172,17 @@ static int madvise_update_vma(vm_flags_t
if (IS_ERR(vma))
return PTR_ERR(vma);
- madv_behavior->vma = vma;
+ /*
+ * If a new vma was created during vma_modify_XXX, the resulting
+ * vma is already locked. Skip re-locking new vma in this case.
+ */
+ if (vma == madv_behavior->vma) {
+ if (vma_start_write_killable(vma))
+ return -EINTR;
+ } else {
+ madv_behavior->vma = vma;
+ }
- /* vm_flags is protected by the mmap_lock held in write mode. */
- vma_start_write(vma);
vma->flags = new_vma_flags;
if (set_new_anon_name)
return replace_anon_vma_name(vma, anon_name);
--- a/mm/memory.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/memory.c
@@ -366,6 +366,8 @@ void free_pgd_range(struct mmu_gather *t
* page tables that should be removed. This can differ from the vma mappings on
* some archs that may have mappings that need to be removed outside the vmas.
* Note that the prev->vm_end and next->vm_start are often used.
+ * We don't use vma_start_write_killable() because page tables should be freed
+ * even if the task is being killed.
*
* The vma_end differs from the pg_end when a dup_mmap() failed and the tree has
* unrelated data to the mm_struct being torn down.
--- a/mm/mempolicy.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/mempolicy.c
@@ -1784,7 +1784,8 @@ SYSCALL_DEFINE4(set_mempolicy_home_node,
return -EINVAL;
if (end == start)
return 0;
- mmap_write_lock(mm);
+ if (mmap_write_lock_killable(mm))
+ return -EINTR;
prev = vma_prev(&vmi);
for_each_vma_range(vmi, vma, end) {
/*
@@ -1801,13 +1802,19 @@ SYSCALL_DEFINE4(set_mempolicy_home_node,
err = -EOPNOTSUPP;
break;
}
+ /*
+ * Lock the VMA early to avoid extra work if fatal signal
+ * is pending.
+ */
+ err = vma_start_write_killable(vma);
+ if (err)
+ break;
new = mpol_dup(old);
if (IS_ERR(new)) {
err = PTR_ERR(new);
break;
}
- vma_start_write(vma);
new->home_node = home_node;
err = mbind_range(&vmi, vma, &prev, start, end, new);
mpol_put(new);
--- a/mm/mlock.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/mlock.c
@@ -419,8 +419,10 @@ out:
*
* Called for mlock(), mlock2() and mlockall(), to set @vma VM_LOCKED;
* called for munlock() and munlockall(), to clear VM_LOCKED from @vma.
+ *
+ * Return: 0 on success, -EINTR if fatal signal is pending.
*/
-static void mlock_vma_pages_range(struct vm_area_struct *vma,
+static int mlock_vma_pages_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end,
vma_flags_t *new_vma_flags)
{
@@ -442,7 +444,9 @@ static void mlock_vma_pages_range(struct
*/
if (vma_flags_test(new_vma_flags, VMA_LOCKED_BIT))
vma_flags_set(new_vma_flags, VMA_IO_BIT);
- vma_start_write(vma);
+ if (vma_start_write_killable(vma))
+ return -EINTR;
+
vma_flags_reset_once(vma, new_vma_flags);
lru_add_drain();
@@ -453,6 +457,7 @@ static void mlock_vma_pages_range(struct
vma_flags_clear(new_vma_flags, VMA_IO_BIT);
vma_flags_reset_once(vma, new_vma_flags);
}
+ return 0;
}
/*
@@ -506,11 +511,15 @@ static int mlock_fixup(struct vma_iterat
*/
if (vma_flags_test(&new_vma_flags, VMA_LOCKED_BIT) &&
vma_flags_test(&old_vma_flags, VMA_LOCKED_BIT)) {
+ ret = vma_start_write_killable(vma);
+ if (ret)
+ goto out; /* mm->locked_vm is fine as nr_pages == 0 */
/* No work to do, and mlocking twice would be wrong */
- vma_start_write(vma);
vma->flags = new_vma_flags;
} else {
- mlock_vma_pages_range(vma, start, end, &new_vma_flags);
+ ret = mlock_vma_pages_range(vma, start, end, &new_vma_flags);
+ if (ret)
+ mm->locked_vm -= nr_pages;
}
out:
*prev = vma;
@@ -739,9 +748,18 @@ static int apply_mlockall_flags(int flag
error = mlock_fixup(&vmi, vma, &prev, vma->vm_start, vma->vm_end,
newflags);
- /* Ignore errors, but prev needs fixing up. */
- if (error)
+ if (error) {
+ /*
+ * If we failed due to a pending fatal signal, return
+ * now. If we locked the vma before signal arrived, it
+ * will be unlocked when we drop mmap_write_lock.
+ */
+ if (fatal_signal_pending(current))
+ return -EINTR;
+
+ /* Ignore errors, but prev needs fixing up. */
prev = vma;
+ }
cond_resched();
}
out:
--- a/mm/mprotect.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/mprotect.c
@@ -716,6 +716,7 @@ mprotect_fixup(struct vma_iterator *vmi,
const vma_flags_t old_vma_flags = READ_ONCE(vma->flags);
vma_flags_t new_vma_flags = legacy_to_vma_flags(newflags);
long nrpages = (end - start) >> PAGE_SHIFT;
+ struct vm_area_struct *new_vma;
unsigned int mm_cp_flags = 0;
unsigned long charged = 0;
int error;
@@ -772,19 +773,27 @@ mprotect_fixup(struct vma_iterator *vmi,
vma_flags_clear(&new_vma_flags, VMA_ACCOUNT_BIT);
}
- vma = vma_modify_flags(vmi, *pprev, vma, start, end, &new_vma_flags);
- if (IS_ERR(vma)) {
- error = PTR_ERR(vma);
+ new_vma = vma_modify_flags(vmi, *pprev, vma, start, end,
+ &new_vma_flags);
+ if (IS_ERR(new_vma)) {
+ error = PTR_ERR(new_vma);
goto fail;
}
- *pprev = vma;
-
/*
- * vm_flags and vm_page_prot are protected by the mmap_lock
- * held in write mode.
+ * If a new vma was created during vma_modify_flags, the resulting
+ * vma is already locked. Skip re-locking new vma in this case.
*/
- vma_start_write(vma);
+ if (new_vma == vma) {
+ error = vma_start_write_killable(vma);
+ if (error)
+ goto fail;
+ } else {
+ vma = new_vma;
+ }
+
+ *pprev = vma;
+
vma_flags_reset_once(vma, &new_vma_flags);
if (vma_wants_manual_pte_write_upgrade(vma))
mm_cp_flags |= MM_CP_TRY_CHANGE_WRITABLE;
--- a/mm/mremap.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/mremap.c
@@ -1348,6 +1348,11 @@ static unsigned long move_vma(struct vma
if (err)
return err;
+ /* We don't want racing faults. */
+ err = vma_start_write_killable(vrm->vma);
+ if (err)
+ return err;
+
/*
* If accounted, determine the number of bytes the operation will
* charge.
@@ -1355,9 +1360,6 @@ static unsigned long move_vma(struct vma
if (!vrm_calc_charge(vrm))
return -ENOMEM;
- /* We don't want racing faults. */
- vma_start_write(vrm->vma);
-
/* Perform copy step. */
err = copy_vma_and_data(vrm, &new_vma);
/*
--- a/mm/mseal.c~mm-use-vma_start_write_killable-in-mm-syscalls
+++ a/mm/mseal.c
@@ -70,14 +70,28 @@ static int mseal_apply(struct mm_struct
if (!vma_test(vma, VMA_SEALED_BIT)) {
vma_flags_t vma_flags = vma->flags;
+ struct vm_area_struct *new_vma;
vma_flags_set(&vma_flags, VMA_SEALED_BIT);
- vma = vma_modify_flags(&vmi, prev, vma, curr_start,
- curr_end, &vma_flags);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
- vma_start_write(vma);
+ new_vma = vma_modify_flags(&vmi, prev, vma, curr_start,
+ curr_end, &vma_flags);
+ if (IS_ERR(new_vma))
+ return PTR_ERR(new_vma);
+
+ /*
+ * If a new vma was created during vma_modify_flags,
+ * the resulting vma is already locked.
+ * Skip re-locking new vma in this case.
+ */
+ if (new_vma == vma) {
+ int err = vma_start_write_killable(vma);
+ if (err)
+ return err;
+ } else {
+ vma = new_vma;
+ }
+
vma_set_flags(vma, VMA_SEALED_BIT);
}
_
Patches currently in -mm which might be from surenb@google.com are
mm-vma-cleanup-error-handling-path-in-vma_expand.patch
mm-use-vma_start_write_killable-in-mm-syscalls.patch
mm-khugepaged-use-vma_start_write_killable-in-collapse_huge_page.patch
mm-vma-use-vma_start_write_killable-in-vma-operations.patch
mm-use-vma_start_write_killable-in-process_vma_walk_lock.patch
kvm-ppc-use-vma_start_write_killable-in-kvmppc_memslot_page_merge.patch
mm-vmscan-prevent-mglru-reclaim-from-pinning-address-space.patch
next reply other threads:[~2026-03-27 23:12 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 23:12 Andrew Morton [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-03-27 17:00 + mm-use-vma_start_write_killable-in-mm-syscalls.patch added to mm-new branch Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260327231252.B386EC19423@smtp.kernel.org \
--to=akpm@linux-foundation.org \
--cc=mm-commits@vger.kernel.org \
--cc=surenb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.