Re: [PATCHv7 13/18] mm: Drop fake head checks
From: Kiryl Shutsemau
Date: Tue Oct 27 2026 - 08:58:47 EST
On Tue, Oct 27, 2026 at 01:13:23PM +0100, Peter Zijlstra wrote:
> On Tue, Oct 27, 2026 at 12:00:47PM +0000, Kiryl Shutsemau wrote:
>
> > Fair enough. Here's some context.
> >
> > HVO (HugeTLB Vmemmap Optimization) frees most of the memmap of a hugetlb
> > folio by remapping the struct pages after the first vmemmap page to a
> > shared page, mapped read-only.
> >
> > Every lockless get of a page reference (e.g. page cache lookup, PFN
> > scanners) relies on page_ref_add_unless_zero(), which is
> > atomic_add_unless(&page->_refcount, nr, 0).
> >
> > The page can be freed and reused between finding it and the get; the
> > zero refcount is what makes the get fail. The race:
> >
> > lockless get other CPU
> > c = atomic_read(&page->_refcount)
> > c != 0
> > page freed
> > page allocated as a hugetlb tail
> > HVO remaps it read-only
> > try_cmpxchg(&page->_refcount, &c, c + nr)
> > -> write fault on read-only vmemmap
>
> I missed a little something here; page->_refcount is in the page-frame;
> how does the page itself being RO affect this?
Emm. I am not sure I follow the question.
The memory itself is not touched. HVO remaps the vmemmap, the array of
struct pages: the part that holds the folio's tail struct pages points
to the shared page, mapped PAGE_KERNEL_RO. So it is the struct page,
and its _refcount, that is read-only.
For a 2M folio with 4K pages, its struct pages take 8 pages of vmemmap;
the last 7 of them map to that one RO page.
--
Kiryl Shutsemau / Kirill A. Shutemov