Commit eac8ea87 authored by Wei Yang's avatar Wei Yang Committed by Mike Rapoport (Microsoft)
Browse files

mm/memblock: repeat setting reserved region nid if array is doubled



Commit 61167ad5 ("mm: pass nid to reserve_bootmem_region()") introduce
a way to set nid to all reserved region.

But there is a corner case it will leave some region with invalid nid.
When memblock_set_node() doubles the array of memblock.reserved, it may
lead to a new reserved region before current position. The new region
will be left with an invalid node id.

Repeat the process when detecting it.

Fixes: 61167ad5 ("mm: pass nid to reserve_bootmem_region()")
Signed-off-by: default avatarWei Yang <richard.weiyang@gmail.com>
CC: Mike Rapoport <rppt@kernel.org>
CC: Yajun Deng <yajun.deng@linux.dev>
CC: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20250318071948.23854-3-richard.weiyang@gmail.com


Signed-off-by: default avatarMike Rapoport (Microsoft) <rppt@kernel.org>
parent 06eaa824
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2183,11 +2183,14 @@ static void __init memmap_init_reserved_pages(void)
	struct memblock_region *region;
	phys_addr_t start, end;
	int nid;
	unsigned long max_reserved;

	/*
	 * set nid on all reserved pages and also treat struct
	 * pages for the NOMAP regions as PageReserved
	 */
repeat:
	max_reserved = memblock.reserved.max;
	for_each_mem_region(region) {
		nid = memblock_get_region_node(region);
		start = region->base;
@@ -2198,6 +2201,13 @@ static void __init memmap_init_reserved_pages(void)

		memblock_set_node(start, region->size, &memblock.reserved, nid);
	}
	/*
	 * 'max' is changed means memblock.reserved has been doubled its
	 * array, which may result a new reserved region before current
	 * 'start'. Now we should repeat the procedure to set its node id.
	 */
	if (max_reserved != memblock.reserved.max)
		goto repeat;

	/*
	 * initialize struct pages for reserved regions that don't have