[RFC PATCH 4/8] mm/vmalloc: Eliminate page table zigzag for huge vmalloc mappings
Barry Song
baohua at kernel.org
Mon Apr 13 12:49:55 PDT 2026
On Tue, Apr 14, 2026 at 12:16 AM Mike Rapoport <rppt at kernel.org> wrote:
>
> On Wed, Apr 08, 2026 at 10:51:11AM +0800, Barry Song (Xiaomi) wrote:
> > For vmalloc() allocations with VM_ALLOW_HUGE_VMAP, we no longer
> > need to iterate over pages one by one, which would otherwise lead to
> > zigzag page table mappings.
> >
> > The code is now unified with the PAGE_SHIFT case by simply
> > calling vmap_small_pages_range_noflush().
> >
> > Signed-off-by: Barry Song (Xiaomi) <baohua at kernel.org>
> > ---
> > mm/vmalloc.c | 22 ++++------------------
> > 1 file changed, 4 insertions(+), 18 deletions(-)
> >
> > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > index 5bf072297536..eba436386929 100644
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -689,27 +689,13 @@ static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
> > int __vmap_pages_range_noflush(unsigned long addr, unsigned long end,
> > pgprot_t prot, struct page **pages, unsigned int page_shift)
> > {
> > - unsigned int i, nr = (end - addr) >> PAGE_SHIFT;
> > -
> > WARN_ON(page_shift < PAGE_SHIFT);
> >
> > - if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC) ||
> > - page_shift == PAGE_SHIFT)
> > - return vmap_small_pages_range_noflush(addr, end, prot, pages, PAGE_SHIFT);
> > -
> > - for (i = 0; i < nr; i += 1U << (page_shift - PAGE_SHIFT)) {
> > - int err;
> > -
> > - err = vmap_range_noflush(addr, addr + (1UL << page_shift),
> > - page_to_phys(pages[i]), prot,
> > - page_shift);
> > - if (err)
> > - return err;
> > + if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC))
> > + page_shift = PAGE_SHIFT;
> >
> > - addr += 1UL << page_shift;
> > - }
> > -
> > - return 0;
> > + return vmap_small_pages_range_noflush(addr, end, prot, pages,
> > + min(page_shift, PMD_SHIFT));
>
> Wouldn't vmap_range_noflush() already "do the right thing" even without
> changes to vmap_small_pages_range_noflush()?
vmap_range_noflush does the right thing for the contiguous physical
address - ioremap case where we map contiguous physical addresses
for iomem etc.
for pages array, they are not contiguous physical addresses. they might be
multiple contiguous physical addresses, but they are not contiguous as
a whole.
>
> > }
> >
> > int vmap_pages_range_noflush(unsigned long addr, unsigned long end,
> > --
Thanks
Barry
More information about the linux-arm-kernel
mailing list