summaryrefslogtreecommitdiff
path: root/mm/memblock.c
diff options
context:
space:
mode:
authorYajun Deng <yajun.deng@linux.dev>2023-06-19 10:34:06 +0800
committerAndrew Morton <akpm@linux-foundation.org>2023-06-23 16:59:27 -0700
commit61167ad5fecdeaa037f3df1ba354dddd5f66a1ed (patch)
treeb0e08754150ba76f267e9181f2a6173f2d99776c /mm/memblock.c
parent9883c7f84053cec2826ca3c56254601b5ce9cdbe (diff)
downloadlwn-61167ad5fecdeaa037f3df1ba354dddd5f66a1ed.tar.gz
lwn-61167ad5fecdeaa037f3df1ba354dddd5f66a1ed.zip
mm: pass nid to reserve_bootmem_region()
early_pfn_to_nid() is called frequently in init_reserved_page(), it returns the node id of the PFN. These PFN are probably from the same memory region, they have the same node id. It's not necessary to call early_pfn_to_nid() for each PFN. Pass nid to reserve_bootmem_region() and drop the call to early_pfn_to_nid() in init_reserved_page(). Also, set nid on all reserved pages before doing this, as some reserved memory regions may not be set nid. The most beneficial function is memmap_init_reserved_pages() if CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled. The following data was tested on an x86 machine with 190GB of RAM. before: memmap_init_reserved_pages() 67ms after: memmap_init_reserved_pages() 20ms Link: https://lkml.kernel.org/r/20230619023406.424298-1-yajun.deng@linux.dev Signed-off-by: Yajun Deng <yajun.deng@linux.dev> Reviewed-by: Mike Rapoport (IBM) <rppt@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/memblock.c')
-rw-r--r--mm/memblock.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/mm/memblock.c b/mm/memblock.c
index da4264528e1e..46739551d4d1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -2082,19 +2082,30 @@ static void __init memmap_init_reserved_pages(void)
{
struct memblock_region *region;
phys_addr_t start, end;
- u64 i;
+ int nid;
+
+ /*
+ * set nid on all reserved pages and also treat struct
+ * pages for the NOMAP regions as PageReserved
+ */
+ for_each_mem_region(region) {
+ nid = memblock_get_region_node(region);
+ start = region->base;
+ end = start + region->size;
+
+ if (memblock_is_nomap(region))
+ reserve_bootmem_region(start, end, nid);
+
+ memblock_set_node(start, end, &memblock.reserved, nid);
+ }
/* initialize struct pages for the reserved regions */
- for_each_reserved_mem_range(i, &start, &end)
- reserve_bootmem_region(start, end);
+ for_each_reserved_mem_region(region) {
+ nid = memblock_get_region_node(region);
+ start = region->base;
+ end = start + region->size;
- /* and also treat struct pages for the NOMAP regions as PageReserved */
- for_each_mem_region(region) {
- if (memblock_is_nomap(region)) {
- start = region->base;
- end = start + region->size;
- reserve_bootmem_region(start, end);
- }
+ reserve_bootmem_region(start, end, nid);
}
}