Skip to content

Commit 9037a99

Browse files
Michal Hockotorvalds
authored andcommitted
mm, memory_hotplug: split up register_one_node()
Memory hotplug (add_memory_resource) has to reinitialize node infrastructure if the node is offline (one which went through the complete add_memory(); remove_memory() cycle). That involves node registration to the kobj infrastructure (register_node), the proper association with cpus (register_cpu_under_node) and finally creation of node<->memblock symlinks (link_mem_sections). The last part requires to know node_start_pfn and node_spanned_pages which we currently have but a leter patch will postpone this initialization to the onlining phase which happens later. In fact we do not need to rely on the early pgdat initialization even now because the currently hot added pfn range is currently known. Split register_one_node into core which does all the common work for the boot time NUMA initialization and the hotplug (__register_one_node). register_one_node keeps the full initialization while hotplug calls __register_one_node and manually calls link_mem_sections for the proper range. This shouldn't introduce any functional change. Link: http://lkml.kernel.org/r/20170515085827.16474-6-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Andi Kleen <ak@linux.intel.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Balbir Singh <bsingharora@gmail.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Daniel Kiper <daniel.kiper@oracle.com> Cc: David Rientjes <rientjes@google.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jerome Glisse <jglisse@redhat.com> Cc: Joonsoo Kim <js1304@gmail.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Reza Arbab <arbab@linux.vnet.ibm.com> Cc: Tobias Regnery <tobias.regnery@gmail.com> Cc: Toshi Kani <toshi.kani@hpe.com> Cc: Vitaly Kuznetsov <vkuznets@redhat.com> Cc: Xishi Qiu <qiuxishi@huawei.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 1b862ae commit 9037a99

File tree

3 files changed

+70
-33
lines changed

3 files changed

+70
-33
lines changed

drivers/base/node.c

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -461,10 +461,9 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
461461
return 0;
462462
}
463463

464-
static int link_mem_sections(int nid)
464+
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
465465
{
466-
unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
467-
unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
466+
unsigned long end_pfn = start_pfn + nr_pages;
468467
unsigned long pfn;
469468
struct memory_block *mem_blk = NULL;
470469
int err = 0;
@@ -552,10 +551,7 @@ static int node_memory_callback(struct notifier_block *self,
552551
return NOTIFY_OK;
553552
}
554553
#endif /* CONFIG_HUGETLBFS */
555-
#else /* !CONFIG_MEMORY_HOTPLUG_SPARSE */
556-
557-
static int link_mem_sections(int nid) { return 0; }
558-
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
554+
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
559555

560556
#if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \
561557
!defined(CONFIG_HUGETLBFS)
@@ -569,39 +565,32 @@ static void init_node_hugetlb_work(int nid) { }
569565

570566
#endif
571567

572-
int register_one_node(int nid)
568+
int __register_one_node(int nid)
573569
{
574-
int error = 0;
570+
int p_node = parent_node(nid);
571+
struct node *parent = NULL;
572+
int error;
575573
int cpu;
576574

577-
if (node_online(nid)) {
578-
int p_node = parent_node(nid);
579-
struct node *parent = NULL;
580-
581-
if (p_node != nid)
582-
parent = node_devices[p_node];
583-
584-
node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
585-
if (!node_devices[nid])
586-
return -ENOMEM;
587-
588-
error = register_node(node_devices[nid], nid, parent);
575+
if (p_node != nid)
576+
parent = node_devices[p_node];
589577

590-
/* link cpu under this node */
591-
for_each_present_cpu(cpu) {
592-
if (cpu_to_node(cpu) == nid)
593-
register_cpu_under_node(cpu, nid);
594-
}
578+
node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
579+
if (!node_devices[nid])
580+
return -ENOMEM;
595581

596-
/* link memory sections under this node */
597-
error = link_mem_sections(nid);
582+
error = register_node(node_devices[nid], nid, parent);
598583

599-
/* initialize work queue for memory hot plug */
600-
init_node_hugetlb_work(nid);
584+
/* link cpu under this node */
585+
for_each_present_cpu(cpu) {
586+
if (cpu_to_node(cpu) == nid)
587+
register_cpu_under_node(cpu, nid);
601588
}
602589

603-
return error;
590+
/* initialize work queue for memory hot plug */
591+
init_node_hugetlb_work(nid);
604592

593+
return error;
605594
}
606595

607596
void unregister_one_node(int nid)

include/linux/node.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,38 @@ struct memory_block;
3030
extern struct node *node_devices[];
3131
typedef void (*node_registration_func_t)(struct node *);
3232

33+
#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
34+
extern int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages);
35+
#else
36+
static inline int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
37+
{
38+
return 0;
39+
}
40+
#endif
41+
3342
extern void unregister_node(struct node *node);
3443
#ifdef CONFIG_NUMA
35-
extern int register_one_node(int nid);
44+
/* Core of the node registration - only memory hotplug should use this */
45+
extern int __register_one_node(int nid);
46+
47+
/* Registers an online node */
48+
static inline int register_one_node(int nid)
49+
{
50+
int error = 0;
51+
52+
if (node_online(nid)) {
53+
struct pglist_data *pgdat = NODE_DATA(nid);
54+
55+
error = __register_one_node(nid);
56+
if (error)
57+
return error;
58+
/* link memory sections under this node */
59+
error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages);
60+
}
61+
62+
return error;
63+
}
64+
3665
extern void unregister_one_node(int nid);
3766
extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
3867
extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
@@ -46,6 +75,10 @@ extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
4675
node_registration_func_t unregister);
4776
#endif
4877
#else
78+
static inline int __register_one_node(int nid)
79+
{
80+
return 0;
81+
}
4982
static inline int register_one_node(int nid)
5083
{
5184
return 0;

mm/memory_hotplug.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,22 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
13881388
node_set_online(nid);
13891389

13901390
if (new_node) {
1391-
ret = register_one_node(nid);
1391+
unsigned long start_pfn = start >> PAGE_SHIFT;
1392+
unsigned long nr_pages = size >> PAGE_SHIFT;
1393+
1394+
ret = __register_one_node(nid);
1395+
if (ret)
1396+
goto register_fail;
1397+
1398+
/*
1399+
* link memory sections under this node. This is already
1400+
* done when creatig memory section in register_new_memory
1401+
* but that depends to have the node registered so offline
1402+
* nodes have to go through register_node.
1403+
* TODO clean up this mess.
1404+
*/
1405+
ret = link_mem_sections(nid, start_pfn, nr_pages);
1406+
register_fail:
13921407
/*
13931408
* If sysfs file of new node can't create, cpu on the node
13941409
* can't be hot-added. There is no rollback way now.

0 commit comments

Comments
 (0)