Re: [PATCH v8 03/10] mm/vmalloc: use pte_set_huge()/pte_clear_huge() for PTE-level block mappings

From: Wen Jiang

Date: Fri Sep 18 2026 - 04:38:09 EST


On Fri, 18 Sept 2026 at 15:04, Christophe Leroy (CS GROUP)
<chleroy@xxxxxxxxxx> wrote:
>
>
>
> Le 18/09/2026 à 08:14, Barry Song a écrit :
> > On Fri, Sep 18, 2026 at 2:05 PM Christophe Leroy (CS GROUP)
> > <chleroy@xxxxxxxxxx> wrote:
> >>
> >>
> >>
> >> Le 17/09/2026 à 23:44, Barry Song a écrit :
> >>> On Thu, Sep 17, 2026 at 10:41 PM Wen Jiang <jiangwenxiaomi@xxxxxxxxx> wrote:
> > [...]
> >
> >>>>>>
> >>>>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> >>>>>> index cdd68ed3ae1a9..349ced999f959 100644
> >>>>>> --- a/include/linux/pgtable.h
> >>>>>> +++ b/include/linux/pgtable.h
> >>>>>> @@ -2134,6 +2134,35 @@ static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
> >>>>>> }
> >>>>>> #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
> >>>>>>
> >>>>>> +/*
> >>>>>> + * PTE-level block mappings for vmap.
> >>>>>> + *
> >>>>>> + * pte_set_huge() only has to be implemented by architectures whose
> >>>>>> + * arch_vmap_pte_range_map_size() can return a size other than PAGE_SIZE.
> >>>>>> + */
> >>>>>> +#ifndef __HAVE_ARCH_PTE_SET_HUGE
> >>>>>> +static inline void pte_set_huge(pte_t *ptep, unsigned long addr,
> >>>>>> + phys_addr_t phys, pgprot_t prot,
> >>>>>> + unsigned long size)
> >>>>>> +{
> >>>>>> + WARN_ON_ONCE(1);
> >>>>>
> >>>>> BUILD_BUG_ON() would be better here.
> >>>>>
> >>>>> It should be possible because fallback arch_vmap_pte_range_map_size()
> >>>>> will constant-fold PAGE_SIZE so pte_set_huge() will never be called.
> >>>>>
> >>>>
> >>>> Agreed. These fallbacks exist only to keep the build working on
> >>>> architectures with PTE-level block mappings and should never actually
> >>>> be reached, so BUILD_BUG_ON() is right. I'll make that change in v9.
> >>>>
> >>>
> >>> I am not quite sure. It won't be called at runtime because
> >>> `vmap size`/`unmap size` return `PAGE_SIZE`, so the code won't
> >>> reach this branch. But it will still be built.
> >>
> >> The fallbacks are defined as:
> >>
> >> #ifndef arch_vmap_pte_range_map_size
> >> static inline unsigned long arch_vmap_pte_range_map_size(unsigned long
> >> addr, unsigned long end,
> >> u64 pfn, unsigned int max_page_shift)
> >> {
> >> return PAGE_SIZE;
> >> }
> >> #endif
> >>
> >> #ifndef arch_vmap_pte_range_unmap_size
> >> static inline unsigned long arch_vmap_pte_range_unmap_size(unsigned long
> >> addr,
> >> pte_t *ptep)
> >> {
> >> return PAGE_SIZE;
> >> }
> >> #endif
> >>
> >> Therefore in:
> >>
> >> size = arch_vmap_pte_range_unmap_size(addr, pte);
> >> if (size != PAGE_SIZE) {
> >>
> >> GCC knows 'size' is const and its value is PAGE_SIZE, so it won't emit
> >> the branch at all.
> >>
> >> It is call constant folding, some explanation here:
> >> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FConstant_folding&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C869dac21f28d45988a3d08df154c225a%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639253088878897551%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Dvtz1%2FAHvAbVYO%2BRaHTOizcD%2FclJ9FqTcWXKMhIFVyw%3D&reserved=0
> >>
> >>>
> >>> So, would a `BUILD_BUG_ON()` trigger a build failure here?
> >>
> >> It shouldn't, if it does it is a compiled bug or this is because someone
> >> has redefined arch_vmap_pte_range_map_size() and not pte_set_huge()
> >> which we'd better know at build time rather than at runtime.
> >
> > Thanks, Christophe. I was also thinking about compiler optimization. I
> > was just a bit worried that we're touching the common MM code, which
> > affects almost all architectures, so I'm not quite sure whether this is
> > supported by all GCC versions used by those architectures.
> >
> > If it is supported by all of them, I agree that `BUILD_BUG_ON()` is a
> > perfect approach.
>
> AFAIU this is the assumption made by the kernel, see
> https://docs.kernel.org/process/coding-style.html#conditional-compilation
>
> This is the same compiler, I see no reason why ability to constant-fold
> would be dependant on architecture.
>
> Christophe

Hi Barry and Christophe,

pgtable.h already does this in a few places, the !THP fallback of
pmdp_clear_flush_young() is just BUILD_BUG(), and its caller in mm/rmap.c,
a file that is built unconditionally, is guarded by
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) rather than #ifdef. So on every
THP=n build, on every architecture, that call has to be eliminated by
the compiler or the build breaks.

I built it with BUILD_BUG() on x86_64, arm64 and powerpc (8xx) to be sure,
and all three are clean.

It will be BUILD_BUG() rather than BUILD_BUG_ON(1): BUILD_BUG_ON() expects a
condition the compiler should know is false, while BUILD_BUG() is documented
as the way to flag code that is expected to be eliminated at build time.

Thanks,
Wen