On Sun, Apr 05, 2026 at 08:52:00PM +0800, Muchun Song wrote:
> When vmemmap pages allocation or usemap allocation fails, sparse_init_nid()
> currently only marks the corresponding section as non-present. However,
> subsequent code like memmap_init() iterating over PFNs does not check for
> non-present sections, leading to invalid memory access (additional,
> subsection_map_init() accessing the unallocated usemap as well).
> 
> It is complex to audit and fix all boot-time PFN iterators to handle these
> partially initialized sections correctly. Since vmemmap and usemap allocation
> failures are extremely rare during early boot, the more appropriate approach
> is to expose the problem as early as possible.
> 
> Therefore, use BUG_ON() to panic immediately if allocation fails, instead of
> attempting a partial recovery that leads to obscure crashes later.
> 
> Signed-off-by: Muchun Song <[email protected]>

Acked-by: Mike Rapoport (Microsoft) <[email protected]>

> ---
>  mm/sparse.c | 37 ++++++++-----------------------------
>  1 file changed, 8 insertions(+), 29 deletions(-)
> 
> diff --git a/mm/sparse.c b/mm/sparse.c
> index effdac6b0ab1..5c12b979a618 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -354,19 +354,15 @@ static void __init sparse_init_nid(int nid, unsigned 
> long pnum_begin,
>                                  unsigned long map_count)
>  {
>       unsigned long pnum;
> -     struct page *map;
> -     struct mem_section *ms;
> -
> -     if (sparse_usage_init(nid, map_count)) {
> -             pr_err("%s: node[%d] usemap allocation failed", __func__, nid);
> -             goto failed;
> -     }
>  
> +     if (sparse_usage_init(nid, map_count))
> +             panic("The node[%d] usemap allocation failed\n", nid);

Please consider using memblock_alloc_or_panic() in sparse_usage_init(), it
would simplify the code even more.

>       sparse_buffer_init(map_count * section_map_size(), nid);
>  
>       sparse_vmemmap_init_nid_early(nid);
>  
>       for_each_present_section_nr(pnum_begin, pnum) {
> +             struct mem_section *ms;
>               unsigned long pfn = section_nr_to_pfn(pnum);
>  
>               if (pnum >= pnum_end)
> @@ -374,16 +370,12 @@ static void __init sparse_init_nid(int nid, unsigned 
> long pnum_begin,
>  
>               ms = __nr_to_section(pnum);
>               if (!preinited_vmemmap_section(ms)) {
> +                     struct page *map;
> +
>                       map = __populate_section_memmap(pfn, PAGES_PER_SECTION,
> -                                     nid, NULL, NULL);
> -                     if (!map) {
> -                             pr_err("%s: node[%d] memory map backing failed. 
> Some memory will not be available.",
> -                                    __func__, nid);
> -                             pnum_begin = pnum;
> -                             sparse_usage_fini();
> -                             sparse_buffer_fini();
> -                             goto failed;
> -                     }
> +                                                     nid, NULL, NULL);
> +                     if (!map)
> +                             panic("Populate section (%ld) on node[%d] 
> failed\n", pnum, nid);
>                       memmap_boot_pages_add(DIV_ROUND_UP(PAGES_PER_SECTION * 
> sizeof(struct page),
>                                                          PAGE_SIZE));
>                       sparse_init_early_section(nid, map, pnum, 0);
> @@ -391,19 +383,6 @@ static void __init sparse_init_nid(int nid, unsigned 
> long pnum_begin,
>       }
>       sparse_usage_fini();
>       sparse_buffer_fini();
> -     return;
> -failed:
> -     /*
> -      * We failed to allocate, mark all the following pnums as not present,
> -      * except the ones already initialized earlier.
> -      */
> -     for_each_present_section_nr(pnum_begin, pnum) {
> -             if (pnum >= pnum_end)
> -                     break;
> -             ms = __nr_to_section(pnum);
> -             if (!preinited_vmemmap_section(ms))
> -                     ms->section_mem_map = 0;
> -     }
>  }
>  
>  /*
> -- 
> 2.20.1
> 

-- 
Sincerely yours,
Mike.

Reply via email to