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.
