From a24270cca658886a78d57ede55c0fe0996063025 Mon Sep 17 00:00:00 2001 From: Shijie Luo Date: Wed, 21 Jul 2021 17:43:11 +0800 Subject: [PATCH] mm: alloc pages for pmem from peer node euleros inclusion category: feature feature: etmem bugzilla: 48246 ------------------------------------------------- Pmem is slower than dram. So alloc pages from pmem's peer dram node to accelerate access to pmem page struct. Signed-off-by: Shijie Luo Signed-off-by: Kemeng Shi Reviewed-by: louhongxiang --- include/linux/mm.h | 2 +- kernel/sysctl.c | 9 +++++++++ mm/memory_hotplug.c | 1 + mm/sparse-vmemmap.c | 8 ++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index b370c9bb9f89..c24da9b0870c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3056,7 +3056,7 @@ extern int sysctl_memory_failure_recovery; extern void shake_page(struct page *p, int access); extern atomic_long_t num_poisoned_pages __read_mostly; extern int soft_offline_page(unsigned long pfn, int flags); - +extern unsigned int sysctl_vmemmap_block_from_dram; /* * Error handlers for various types of pages. diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4fbc106aa195..7c52ac56d88d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -3158,6 +3158,15 @@ static struct ctl_table vm_table[] = { .extra2 = SYSCTL_ONE, }, #endif + { + .procname = "vmemmap_block_from_dram", + .data = &sysctl_vmemmap_block_from_dram, + .maxlen = sizeof(sysctl_vmemmap_block_from_dram), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, { } }; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index b9de2df5b835..949d28e66e59 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -914,6 +914,7 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid) /* we can use NODE_DATA(nid) from here */ pgdat->node_id = nid; pgdat->node_start_pfn = 0; + pgdat->peer_node = find_best_peer_node(nid); /* init node's zones as empty zones, we don't have any present pages.*/ free_area_init_core_hotplug(nid); diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 16183d85a7d5..1ed6b19d7232 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -30,6 +30,8 @@ #include #include +unsigned int sysctl_vmemmap_block_from_dram; + /* * Allocate a block of memory to be used to back the virtual memory map * or to back the page tables that are used to create the mapping. @@ -54,6 +56,12 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node) static bool warned; struct page *page; + /* if node is pmem node, alloc_pages from it's peer + * dram node to accelerate access to page struct + */ + if (is_node_pmem(node) && sysctl_vmemmap_block_from_dram) + node = NODE_DATA(node)->peer_node; + page = alloc_pages_node(node, gfp_mask, order); if (page) return page_address(page); -- GitLab