Skip to content

Commit fc44f7f

Browse files
Pavel Tatashintorvalds
Pavel Tatashin
authored andcommitted
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. [[email protected]: s/register_new_memory()/hotplug_memory_register()] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Pavel Tatashin <[email protected]> Acked-by: Michal Hocko <[email protected]> Reviewed-by: Ingo Molnar <[email protected]> Cc: Baoquan He <[email protected]> Cc: Bharata B Rao <[email protected]> Cc: Daniel Jordan <[email protected]> Cc: Dan Williams <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Kirill A. Shutemov <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Steven Sistare <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent b77eab7 commit fc44f7f

File tree

5 files changed

+21
-13
lines changed

5 files changed

+21
-13
lines changed

drivers/base/memory.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ static int add_memory_block(int base_section_nr)
712712
* need an interface for the VM to add new memory regions,
713713
* but without onlining it.
714714
*/
715-
int register_new_memory(int nid, struct mem_section *section)
715+
int hotplug_memory_register(int nid, struct mem_section *section)
716716
{
717717
int ret = 0;
718718
struct memory_block *mem;
@@ -731,7 +731,7 @@ int register_new_memory(int nid, struct mem_section *section)
731731
}
732732

733733
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);
735735
out:
736736
mutex_unlock(&mem_sysfs_mutex);
737737
return ret;

drivers/base/node.c

+15-7
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,8 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
399399
}
400400

401401
/* register memory section under specified node if it spans that node */
402-
int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
402+
int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
403+
bool check_nid)
403404
{
404405
int ret;
405406
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)
425426
continue;
426427
}
427428

428-
page_nid = get_nid_for_pfn(pfn);
429-
if (page_nid < 0)
430-
continue;
431-
if (page_nid != nid)
432-
continue;
429+
/*
430+
* We need to check if page belongs to nid only for the boot
431+
* case, during hotplug we know that all pages in the memory
432+
* block belong to the same node.
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+
}
433441
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
434442
&mem_blk->dev.kobj,
435443
kobject_name(&mem_blk->dev.kobj));
@@ -504,7 +512,7 @@ int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
504512

505513
mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
506514

507-
ret = register_mem_sect_under_node(mem_blk, nid);
515+
ret = register_mem_sect_under_node(mem_blk, nid, true);
508516
if (!err)
509517
err = ret;
510518

include/linux/memory.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ extern int register_memory_notifier(struct notifier_block *nb);
109109
extern void unregister_memory_notifier(struct notifier_block *nb);
110110
extern int register_memory_isolate_notifier(struct notifier_block *nb);
111111
extern void unregister_memory_isolate_notifier(struct notifier_block *nb);
112-
extern int register_new_memory(int, struct mem_section *);
112+
int hotplug_memory_register(int nid, struct mem_section *section);
113113
#ifdef CONFIG_MEMORY_HOTREMOVE
114114
extern int unregister_memory_section(struct mem_section *);
115115
#endif

include/linux/node.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ extern void unregister_one_node(int nid);
6767
extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
6868
extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
6969
extern int register_mem_sect_under_node(struct memory_block *mem_blk,
70-
int nid);
70+
int nid, bool check_nid);
7171
extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
7272
unsigned long phys_index);
7373

@@ -97,7 +97,7 @@ static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
9797
return 0;
9898
}
9999
static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
100-
int nid)
100+
int nid, bool check_nid)
101101
{
102102
return 0;
103103
}

mm/memory_hotplug.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
279279
if (!want_memblock)
280280
return 0;
281281

282-
return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
282+
return hotplug_memory_register(nid, __pfn_to_section(phys_start_pfn));
283283
}
284284

285285
/*

0 commit comments

Comments
 (0)