From: Guilherme Giacomo Simoes <trintaeoitogc@gmail.com>
To: pfalcato@suse.de
Cc: akpm@linux-foundation.org, david@kernel.org, harry@kernel.org,
jannh@google.com, lance.yang@linux.dev, liam@infradead.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org, ljs@kernel.org,
mhocko@suse.com, riel@surriel.com, rppt@kernel.org,
surenb@google.com,
syzbot+395b7abe9696862fc188@syzkaller.appspotmail.com,
trintaeoitogc@gmail.com, vbabka@kernel.org, willy@infradead.org
Subject: Re: [PATCH] mm: fix the race on huge alloc failed
Date: Tue, 1 Sep 2026 08:48:42 -0300 [thread overview]
Message-ID: <20260901114842.26532-1-trintaeoitogc@gmail.com> (raw)
In-Reply-To: <apQxGMgLWWlfn3cd@pedro-suse.lan>
Please, forgive the delay. I really needed spend a long time to understand your
explanation about why this race is safe.
Pedro Falcato <pfalcato@suse.de> wrote:
> > > So it's inappropriate to use READ_ONCE() / WRITE_ONCE() to "solve"
> > > this problem, because we don't need those semantics. It's sufficient
> > > to wrap the read side in data_race() to indicate to KCSAN that we know
> > > what we're doing.
> > you sure?
> >
> > the __anon_vma_prepare(..) is write on vma->anon_vma and the
> > __vmf_anon_prepare(..) is reade from the same vma->anon_vma at the same time,
> > you sure that is not a problem? (I'm asking as a curious layperson.)
>
> 99.9% sure. Here's the basic logic laid out:
>
> 1) Fault needs to fault in anonymous pages
> 2) Fault needs to possibly create an anon_vma
> 2a) Thus it does the lockless check, where indeed we only
> care if it's non-null or not.
> 2b) if the lockless check fails, we get into __anon_vma_prepare()
> logic, which crucially takes the page_table_lock to write the
> anon_vma to the vma. If it takes the lock and something is already
> there, it backs out.
> 3) Now, into the weeds of anon page faulting, we end up in __folio_set_anon(),
> which reads the anon_vma from vma. This function always (AFAIK?) runs with
> the PTE lock held. Thus we can be sure the anon_vma value is correct. In
> any case, we only need to have held the page table lock once in the fault
> for it to be valid; any change to its value from non-null to null needs
> the vma/mmap write lock. Because we take a bunch of locks and do a bunch of
> stuff between that initial check in __vmf_anon_prepare and this, the compiler
> cannot validly cache the load (which can, in theory, tear).
>
> Now, for memory ordering and its wonderful transitive properties:
> 1) writing anon_vma takes the page_table_lock. therefore if you acquire
> page_table_lock, you obsreve the anon_vma store and all preceding stores
> (due to spin_unlock providing RELEASE semantics, and spin_lock providing
> ACQUIRE semantics)
> 2) say you install e.g a PUD entry, you take the page_table_lock. So you fully
> observe the anon_vma that was installed (by doing an ACQUIRE on the lock).
> you also issue a smp_wmb() which makes sure the ptdesc setup is visible.
> 3) others using that PUD entry will (should?) transitively observe everything
> you have observed, data-dependent loads will help you there. If we _ever_
> observe a page table without seeing an associated anon_vma, it's broken.
>
> [Yes, I spent quite a bit of time thinking through this; it isn't trivial to prove
> that 2->3 transition is correct, but it looks vaguely _handwavely_ correct]
So, this race condition is safe just because the ordering (very briefly):
if `if (likely(vma->anon_vma))` is TRUE return 0 (OK)
if `if (likely(vma->anon_vma))` is fail __anon_vma_prepare() is called
6 lines below and inside __anon_vma_prepare() he try to get a lock
`spin_lock(&mm->page_table_lock);` that have ACQUIRE semantics and ensure the
ordering mapping...
if `if (likely(!vma->anon_vma))` (recheck the anon_vma like __vmf_anon_prepare)
fail then `spin_unlock(&mm->page_table_lock);` else alloc anon_mmap.
Thanks for spend time to explain this in detail for me Pedro.
prev parent reply other threads:[~2026-09-01 11:49 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-29 10:00 [PATCH] mm: fix the race on huge alloc failed Guilherme Giacomo Simoes
2026-08-29 15:33 ` Matthew Wilcox
2026-08-29 15:36 ` Matthew Wilcox
2026-08-29 18:02 ` Guilherme Giacomo Simoes
2026-08-30 3:06 ` Lance Yang
2026-08-30 3:34 ` Matthew Wilcox
2026-08-30 12:47 ` Guilherme Giacomo Simoes
2026-08-30 14:07 ` Pedro Falcato
2026-08-31 9:32 ` Lorenzo Stoakes (ARM)
2026-09-01 11:52 ` Guilherme Giacomo Simoes
2026-09-01 11:48 ` Guilherme Giacomo Simoes [this message]
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=20260901114842.26532-1-trintaeoitogc@gmail.com \
--to=trintaeoitogc@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=harry@kernel.org \
--cc=jannh@google.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=pfalcato@suse.de \
--cc=riel@surriel.com \
--cc=rppt@kernel.org \
--cc=surenb@google.com \
--cc=syzbot+395b7abe9696862fc188@syzkaller.appspotmail.com \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
/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.