From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Matthew Wilcox <willy@infradead.org>
Cc: Barry Song <baohua@kernel.org>,
Hongru Zhang <zhanghongru06@gmail.com>,
akpm@linux-foundation.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, surenb@google.com,
david@kernel.org, liam@infradead.org, mhocko@suse.com,
rppt@kernel.org, shakeel.butt@linux.dev, vbabka@kernel.org,
zhaonanzhe@xiaomi.com, linux@armlinux.org.uk,
catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
linux-arm-kernel@lists.infradead.org, chenhuacai@kernel.org,
kernel@xen0n.name, loongarch@lists.linux.dev,
maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,
chleroy@kernel.org, linuxppc-dev@lists.ozlabs.org,
pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu,
alex@ghiti.fr, linux-riscv@lists.infradead.org,
agordeev@linux.ibm.com, gerald.schaefer@linux.ibm.com,
hca@linux.ibm.com, gor@linux.ibm.com, borntraeger@linux.ibm.com,
svens@linux.ibm.com, linux-s390@vger.kernel.org,
dave.hansen@linux.intel.com, luto@kernel.org,
peterz@infradead.org, tglx@kernel.org, mingo@redhat.com,
bp@alien8.de, x86@kernel.org, hpa@zytor.com,
Hongru Zhang <zhanghongru@xiaomi.com>
Subject: Re: [PATCH v6] mm: retry page faults once under the per-VMA lock
Date: Fri, 2 Oct 2026 14:12:35 +0100 [thread overview]
Message-ID: <ar-o1TrOMGrrcxLX@gremlin> (raw)
In-Reply-To: <ar7MsOb6IJLt4eLo@casper.infradead.org>
On Thu, Oct 01, 2026 at 10:12:16PM +0100, Matthew Wilcox wrote:
> So what I didn't realise is that fork() waits for page faults to finish.
> I don't think that's necessary, so we can just stop doing that (whitespace
> damaged):
>
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 4bf26b0f1e6e..e79555247d3a 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1739,9 +1739,6 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
> for_each_vma(vmi, mpnt) {
> struct file *file;
>
> - retval = vma_start_write_killable(mpnt);
> - if (retval < 0)
> - goto loop_out;
> if (vma_test(mpnt, VMA_DONTCOPY_BIT)) {
> retval = vma_iter_clear_gfp(&vmi, mpnt->vm_start,
> mpnt->vm_end, GFP_KERNEL);
>
> I think this is safe. I've booted a kernel with this change, and
I'm afraid it's not safe :)
We already actually did this (by mistake I think?) before. See commit
fb49c455323f ("fork: lock VMAs of the parent process when forking") - we shipped
that in 6.4.0 -> 6.4.2 and it corrupted memory all over the place.
Reports + a consistent reproducer:
https://bugzilla.kernel.org/show_bug.cgi?id=217624
https://lore.kernel.org/all/dbdef34c-3a07-5951-e1ae-e9c6e3cdf51b@kernel.org/
https://lore.kernel.org/all/b198d649-f4bf-b971-31d0-e8433ec2a34c@applied-asynchrony.com/
Also we have asserts for this lock in copy_page_range() and
copy_hugetlb_page_range() which will now fail (and possibly more further down
the stack?)
> My argument for why it's safe is that a thread which takes a page
> fault during fork() might have taken the page fault either before or
> after fork(). The faults will definitely happen in the parent process.
> They may or may not have happened in the child process, which can't
> possibly care whether or not they've happened.
The problem isn't the child it's the parent - copy_page_range() _modifies_ the
_parent_'s page tables in-place, on assumption that nothing else can access
them (for CoW).
And actually nowadays things are _even_ worse, you could also have concurrent
page faults, MADV_DONTNEED, MADV_FREE, MADV_GUARD_INSTALL/REMOVE, UFFDIO_COPY +
UFFDIO_MOVE (yikes) all of which might introduce new issues + would have to be
audited too.
So - it turns out a lot of stuff implicitly assumes VMA write lock now:
1. CoW - deferred TLB flush race
(The issue above)
https://lore.kernel.org/all/20230705171213.2843068-2-surenb@google.com/
This happens because __copy_present_ptes() does wrprotect_ptes() on the parent
without a TLB flush (that's deferred until the end of the fork).
But unfortunately without a VMA write lock something can then replace the page
table entry in the meantime and you can end up with data loss as a result.
Same issue exists with hugetlb wp too. And god only knows with uffd wp :)
2. THP - can destroy parent THP mappings
copy_pmd_range() does:
if (pmd_is_huge(*src_pmd)) { copy_huge_pmd(); ... }
if (pmd_none_or_clear_bad(src_pmd))
continue;
Without the write lock, a concurrent fault can install a huge PMD via
do_huge_pmd_anonymous_page() or filemap_map_pmd()/do_set_pmd().
The issue is that pmd_bad() fires for leaf PMD (ugh) on at least x86 and arm64,
meaning that'll clear the page table entry.
I think Hugh left a comment alluding to this before:
* copy_pmd_range()'s prior pmd_none_or_clear_bad(src_pmd), and the
* error handling here, assume that exclusive mmap_lock on dst and src
* protects anon from unexpected THP transitions; ...
It's like the mess around pmd_trans_unstable() :(
3. copy_pte_range() skips the required pmd_same() recheck assuming write lock
It uses pte_offset_map_rw_nolock() with a dummy pmdval and:
* We already hold the exclusive mmap_lock, the copy_pte_range() and
* retract_page_tables() are using vma->anon_vma to be exclusive, so
* the PTE page is stable, and there is no need to get pmdval and do
* pmd_same() check.
(Probably needs updating for VMA write lock...)
4. The asserts
Mentioned above!
I suspect there's more as well.
Some of it could be changed, but it'd all be at the cost of behaving very
strangely (no VMA lock but mmap write lock) while manipulating things.
And I am not really happy with changing page table entries in the parent VMA
(for CoW) without a VMA write lock held.
I also wonder whether it would achieve all that much really - the issue is with
holding the VMA lock across I/O, anything else that tries to grab a write lock
is going to end up being the new thing that's blocked (mprotect, munmap, mremap,
mlock etc.)
I think doing something like this would need a very significant redesign and I'm
not convinced it's one that really achieves what we want given all the other
cases that'd get blocked by the VMA lock being held still.
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-10-02 13:12 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 2:56 Hongru Zhang
2026-09-21 17:54 ` Lorenzo Stoakes (ARM)
2026-09-21 18:57 ` Matthew Wilcox
2026-09-22 8:55 ` Lorenzo Stoakes (ARM)
2026-09-27 22:55 ` Matthew Wilcox
2026-09-28 2:48 ` Barry Song
2026-10-01 21:12 ` Matthew Wilcox
2026-10-02 13:12 ` Lorenzo Stoakes (ARM) [this message]
2026-10-02 19:30 ` Barry Song
2026-09-23 9:53 ` Hongru Zhang
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=ar-o1TrOMGrrcxLX@gremlin \
--to=ljs@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=baohua@kernel.org \
--cc=borntraeger@linux.ibm.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=chenhuacai@kernel.org \
--cc=chleroy@kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=kernel@xen0n.name \
--cc=liam@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=loongarch@lists.linux.dev \
--cc=luto@kernel.org \
--cc=maddy@linux.ibm.com \
--cc=mark.rutland@arm.com \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=peterz@infradead.org \
--cc=pjw@kernel.org \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=svens@linux.ibm.com \
--cc=tglx@kernel.org \
--cc=vbabka@kernel.org \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=x86@kernel.org \
--cc=zhanghongru06@gmail.com \
--cc=zhanghongru@xiaomi.com \
--cc=zhaonanzhe@xiaomi.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®