summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Tatashin <pasha.tatashin@oracle.com>2018-04-05 19:22:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-06 00:36:25 -0400
commitfc44f7f9231a73821fc858f5bc48883a9e78f6de (patch)
tree52d633c375d235c3fd059d885981e821f0ee31f4
parentb77eab7079d9e477489d2416cceda05d3c1cf21f (diff)
mm/memory_hotplug: don't read nid from struct page during hotplug
During memory hotplugging the probe routine will leave struct pages uninitialized, the same as it is currently done during boot. Therefore, we do not want to access the inside of struct pages before __init_single_page() is called during onlining. Because during hotplug we know that pages in one memory block belong to the same numa node, we can skip the checking. We should keep checking for the boot case. [pasha.tatashin@oracle.com: s/register_new_memory()/hotplug_memory_register()] Link: http://lkml.kernel.org/r/20180228030308.1116-6-pasha.tatashin@oracle.com Link: http://lkml.kernel.org/r/20180215165920.8570-6-pasha.tatashin@oracle.com Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> Acked-by: Michal Hocko <mhocko@suse.com> Reviewed-by: Ingo Molnar <mingo@kernel.org> Cc: Baoquan He <bhe@redhat.com> Cc: Bharata B Rao <bharata@linux.vnet.ibm.com> Cc: Daniel Jordan <daniel.m.jordan@oracle.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Steven Sistare <steven.sistare@oracle.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/base/memory.c4
-rw-r--r--drivers/base/node.c22
-rw-r--r--include/linux/memory.h2
-rw-r--r--include/linux/node.h4
-rw-r--r--mm/memory_hotplug.c2
5 files changed, 21 insertions, 13 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index deb3f029b451..79fcd2bae96b 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -712,7 +712,7 @@ static int add_memory_block(int base_section_nr)
712 * need an interface for the VM to add new memory regions, 712 * need an interface for the VM to add new memory regions,
713 * but without onlining it. 713 * but without onlining it.
714 */ 714 */
715int register_new_memory(int nid, struct mem_section *section) 715int hotplug_memory_register(int nid, struct mem_section *section)
716{ 716{
717 int ret = 0; 717 int ret = 0;
718 struct memory_block *mem; 718 struct memory_block *mem;
@@ -731,7 +731,7 @@ int register_new_memory(int nid, struct mem_section *section)
731 } 731 }
732 732
733 if (mem->section_count == sections_per_block) 733 if (mem->section_count == sections_per_block)
734 ret = register_mem_sect_under_node(mem, nid); 734 ret = register_mem_sect_under_node(mem, nid, false);
735out: 735out:
736 mutex_unlock(&mem_sysfs_mutex); 736 mutex_unlock(&mem_sysfs_mutex);
737 return ret; 737 return ret;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index c5f81fc621ac..92b00a7e6a02 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -399,7 +399,8 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
399} 399}
400 400
401/* register memory section under specified node if it spans that node */ 401/* register memory section under specified node if it spans that node */
402int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) 402int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
403 bool check_nid)
403{ 404{
404 int ret; 405 int ret;
405 unsigned long pfn, sect_start_pfn, sect_end_pfn; 406 unsigned long pfn, sect_start_pfn, sect_end_pfn;
@@ -425,11 +426,18 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
425 continue; 426 continue;
426 } 427 }
427 428
428 page_nid = get_nid_for_pfn(pfn); 429 /*
429 if (page_nid < 0) 430 * We need to check if page belongs to nid only for the boot
430 continue; 431 * case, during hotplug we know that all pages in the memory
431 if (page_nid != nid) 432 * block belong to the same node.
432 continue; 433 */
434 if (check_nid) {
435 page_nid = get_nid_for_pfn(pfn);
436 if (page_nid < 0)
437 continue;
438 if (page_nid != nid)
439 continue;
440 }
433 ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, 441 ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
434 &mem_blk->dev.kobj, 442 &mem_blk->dev.kobj,
435 kobject_name(&mem_blk->dev.kobj)); 443 kobject_name(&mem_blk->dev.kobj));
@@ -504,7 +512,7 @@ int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
504 512
505 mem_blk = find_memory_block_hinted(mem_sect, mem_blk); 513 mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
506 514
507 ret = register_mem_sect_under_node(mem_blk, nid); 515 ret = register_mem_sect_under_node(mem_blk, nid, true);
508 if (!err) 516 if (!err)
509 err = ret; 517 err = ret;
510 518
diff --git a/include/linux/memory.h b/include/linux/memory.h
index f71e732c77b2..9f8cd856ca1e 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -109,7 +109,7 @@ extern int register_memory_notifier(struct notifier_block *nb);
109extern void unregister_memory_notifier(struct notifier_block *nb); 109extern void unregister_memory_notifier(struct notifier_block *nb);
110extern int register_memory_isolate_notifier(struct notifier_block *nb); 110extern int register_memory_isolate_notifier(struct notifier_block *nb);
111extern void unregister_memory_isolate_notifier(struct notifier_block *nb); 111extern void unregister_memory_isolate_notifier(struct notifier_block *nb);
112extern int register_new_memory(int, struct mem_section *); 112int hotplug_memory_register(int nid, struct mem_section *section);
113#ifdef CONFIG_MEMORY_HOTREMOVE 113#ifdef CONFIG_MEMORY_HOTREMOVE
114extern int unregister_memory_section(struct mem_section *); 114extern int unregister_memory_section(struct mem_section *);
115#endif 115#endif
diff --git a/include/linux/node.h b/include/linux/node.h
index 4ece0fee0ffc..41f171861dcc 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -67,7 +67,7 @@ extern void unregister_one_node(int nid);
67extern int register_cpu_under_node(unsigned int cpu, unsigned int nid); 67extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
68extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); 68extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
69extern int register_mem_sect_under_node(struct memory_block *mem_blk, 69extern int register_mem_sect_under_node(struct memory_block *mem_blk,
70 int nid); 70 int nid, bool check_nid);
71extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, 71extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
72 unsigned long phys_index); 72 unsigned long phys_index);
73 73
@@ -97,7 +97,7 @@ static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
97 return 0; 97 return 0;
98} 98}
99static inline int register_mem_sect_under_node(struct memory_block *mem_blk, 99static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
100 int nid) 100 int nid, bool check_nid)
101{ 101{
102 return 0; 102 return 0;
103} 103}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 565048f496f7..477e183a4ac7 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -279,7 +279,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
279 if (!want_memblock) 279 if (!want_memblock)
280 return 0; 280 return 0;
281 281
282 return register_new_memory(nid, __pfn_to_section(phys_start_pfn)); 282 return hotplug_memory_register(nid, __pfn_to_section(phys_start_pfn));
283} 283}
284 284
285/* 285/*