Re: [PATCHv7 13/18] mm: Drop fake head checks

From: Peter Zijlstra

Date: Wed Oct 28 2026 - 09:40:38 EST


On Wed, Oct 28, 2026 at 12:58:11PM +0000, Kiryl Shutsemau wrote:
> On Wed, Oct 28, 2026 at 09:06:35AM +0100, Peter Zijlstra wrote:
> > On Wed, Oct 28, 2026 at 10:38:22AM +0800, Muchun Song wrote:
> > >
> > >
> > > On 2026/10/28 01:51, Kiryl Shutsemau wrote:
> > > > On Tue, Oct 27, 2026 at 10:03:54PM +0800, Muchun Song wrote:
> > > > > Therefore, I am kind of leaning towards removing the RO protection
> > > > > and restoring RW permissions to solve the race.
> > > > Okay, what about this:
> > > >
> > > > From e23ab850837b53cc79d57d58f1cfb4266e745c3d Mon Sep 17 00:00:00 2001
> > > > From: "Kiryl Shutsemau (Meta)" <kas@xxxxxxxxxx>
> > > > Date: Tue, 27 Oct 2026 17:23:47 +0000
> > > > Subject: [PATCH] mm/hugetlb_vmemmap: map the shared tail page writable
> > > >
> > > > page_ref_add_unless_zero() reads the refcount and then updates it with
> > > > a cmpxchg. A lockless get, such as a page cache lookup or a PFN
> > > > scanner, can read a non-zero refcount from a page that is then freed
> > > > and reused as a hugetlb tail page. If HVO remaps its struct page to
> > > > the shared tail page in between, the cmpxchg writes to read-only
> > > > vmemmap:
> > > >
> > > > CPU0 (lockless get) CPU1
> > > > c = atomic_read(&page->_refcount)
> > > > page freed
> > > > page allocated as a hugetlb tail
> > > > HVO remaps the struct page RO
> > > > try_cmpxchg(&page->_refcount, &c, c + 1)
> > > > -> write fault on read-only vmemmap
> > > >
> > > > The refcount is zero by then and the compare fails, but LOCK CMPXCHG on
> > > > x86 writes anyway. The kernel oopses when hugetlb pages are allocated
> > >
> > > Is this an X86-specific issue? If not, I suggest a more generic
> > > description.
> >
> > AFAICT most architectures that implement single compare-and-swap
> > instructions are affected, with the possible exception of s390.
> >
> > That is, sparc, arm64-lse, riscv-Zacas, loonarch-amocas, openrisc (and
> > ia64 for those people keeping the out-of-tree port alive) all require
> > write protection to begin cmpxchg.
> >
> > All the LL/SC architectures should be fine, they'll never get to the SC
> > part.
>
> Only architectures with HVO matter here: x86-64, riscv and loongarch.
> arm64 has had it disabled since 060a2c92d1b6.

Per that commit, could it be re-enabled now that its no longer marked RO?

> riscv and loongarch implement atomic_fetch_add_unless() with LL/SC only,
> no CAS variant, so they see the zero at the load. That leaves x86.

Ah yes, I only looked at the cmpxchg implementation rather than the
fetch_add_unless :/