Re: [PATCH v3 04/10] mm/vmalloc: propagate errors in vmap_pages_p*d_range()
From: Suren Baghdasaryan
Date: Sun Nov 01 2026 - 11:00:58 EST
On Fri, Oct 30, 2026 at 2:16 AM Hao Ge <hao.ge@xxxxxxxxx> wrote:
>
> Hi Dev
>
> Thanks for your review.
>
> On 2026/10/30 15:29, Dev Jain wrote:
> >
> >
> > On 26/10/26 1:33 pm, Hao Ge wrote:
> >> vmap_pages_pmd_range(), vmap_pages_pud_range() and
> >> vmap_pages_p4d_range() return -ENOMEM whenever the level below them
> >> fails. But vmap_pages_pte_range() can also return -EINVAL for a
> >> page without a valid pfn and -EBUSY for a pte that is already
> >> mapped. Pass the error up as-is instead, like the vmap_p*d_range()
> >> helpers for vmap_page_range() do.
> >>
> >> Signed-off-by: Hao Ge <hao.ge@xxxxxxxxx>
> >> ---
> >
> > Fixes?
> >
>
> Sorry, I missed that.
>
> > Reviewed-by: Dev Jain <dev.jain@xxxxxxx>
>
> Thanks! If you have some time, I'd also appreciate a review of the
> remaining patches in the series -- or Suren and Uladzislau, if they
> get a chance. No rush, I know everyone is busy.
Yep, it's in my review queue.
>
> Thanks
> Best Regards
> Hao
>
> >
> >
> >> mm/vmalloc.c | 24 +++++++++++++++---------
> >> 1 file changed, 15 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> >> index 7131f60d1a8e..d60b99b81ec9 100644
> >> --- a/mm/vmalloc.c
> >> +++ b/mm/vmalloc.c
> >> @@ -600,16 +600,18 @@ static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr,
> >> {
> >> pmd_t *pmd;
> >> unsigned long next;
> >> + int err = 0;
> >>
> >> pmd = pmd_alloc_track(&init_mm, pud, addr, mask);
> >> if (!pmd)
> >> return -ENOMEM;
> >> do {
> >> next = pmd_addr_end(addr, end);
> >> - if (vmap_pages_pte_range(pmd, addr, next, prot, pages, nr, mask))
> >> - return -ENOMEM;
> >> + err = vmap_pages_pte_range(pmd, addr, next, prot, pages, nr, mask);
> >> + if (err)
> >> + break;
> >> } while (pmd++, addr = next, addr != end);
> >> - return 0;
> >> + return err;
> >> }
> >>
> >> static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr,
> >> @@ -618,16 +620,18 @@ static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr,
> >> {
> >> pud_t *pud;
> >> unsigned long next;
> >> + int err = 0;
> >>
> >> pud = pud_alloc_track(&init_mm, p4d, addr, mask);
> >> if (!pud)
> >> return -ENOMEM;
> >> do {
> >> next = pud_addr_end(addr, end);
> >> - if (vmap_pages_pmd_range(pud, addr, next, prot, pages, nr, mask))
> >> - return -ENOMEM;
> >> + err = vmap_pages_pmd_range(pud, addr, next, prot, pages, nr, mask);
> >> + if (err)
> >> + break;
> >> } while (pud++, addr = next, addr != end);
> >> - return 0;
> >> + return err;
> >> }
> >>
> >> static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long addr,
> >> @@ -636,16 +640,18 @@ static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long addr,
> >> {
> >> p4d_t *p4d;
> >> unsigned long next;
> >> + int err = 0;
> >>
> >> p4d = p4d_alloc_track(&init_mm, pgd, addr, mask);
> >> if (!p4d)
> >> return -ENOMEM;
> >> do {
> >> next = p4d_addr_end(addr, end);
> >> - if (vmap_pages_pud_range(p4d, addr, next, prot, pages, nr, mask))
> >> - return -ENOMEM;
> >> + err = vmap_pages_pud_range(p4d, addr, next, prot, pages, nr, mask);
> >> + if (err)
> >> + break;
> >> } while (p4d++, addr = next, addr != end);
> >> - return 0;
> >> + return err;
> >> }
> >>
> >> static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
> >