After commit 61167ad5fecdea ("mm: pass nid to reserve_bootmem_region()")Why is it that only "early" but not "late" memblock_reserve() matters? I failed to see the reason because the arch-specific memblock_init() isn't even in the backtrace, which means that *neither* is the culprit.
we get a panic if DEFERRED_STRUCT_PAGE_INIT is enabled:
[snip]
The reason is early memblock_reserve() in memblock_init() set node id
to MAX_NUMNODES, which causes NODE_DATA(nid) be a NULL dereference in"making NODE_DATA(nid) a NULL ..."
reserve_bootmem_region() -> init_reserved_page(). So set all reservedSo the reordering is for being able to override the newly added memblocks' nids to 0, and additionally doing the same for memblock.reserved is the actual fix. Looks okay.
memblocks on Node#0 at initialization to avoid this panic.
Reported-by: WANG Xuerui <git@xxxxxxxxxx>
Signed-off-by: Huacai Chen <chenhuacai@xxxxxxxxxxx>
---
arch/loongarch/kernel/mem.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
index 4a4107a6a965..aed901c57fb4 100644
--- a/arch/loongarch/kernel/mem.c
+++ b/arch/loongarch/kernel/mem.c
@@ -50,7 +50,6 @@ void __init memblock_init(void)
}
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
- memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
/* Reserve the first 2MB */
memblock_reserve(PHYS_OFFSET, 0x200000);
@@ -58,4 +57,7 @@ void __init memblock_init(void)
/* Reserve the kernel text/data/bss */
memblock_reserve(__pa_symbol(&_text),
__pa_symbol(&_end) - __pa_symbol(&_text));
+
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0);
}