mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Michal Hocko](/assets/img/avatar_default.png)
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>
117 lines
3 KiB
C
117 lines
3 KiB
C
/*
|
|
* include/linux/node.h - generic node definition
|
|
*
|
|
* This is mainly for topological representation. We define the
|
|
* basic 'struct node' here, which can be embedded in per-arch
|
|
* definitions of processors.
|
|
*
|
|
* Basic handling of the devices is done in drivers/base/node.c
|
|
* and system devices are handled in drivers/base/sys.c.
|
|
*
|
|
* Nodes are exported via driverfs in the class/node/devices/
|
|
* directory.
|
|
*/
|
|
#ifndef _LINUX_NODE_H_
|
|
#define _LINUX_NODE_H_
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/workqueue.h>
|
|
|
|
struct node {
|
|
struct device dev;
|
|
|
|
#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS)
|
|
struct work_struct node_work;
|
|
#endif
|
|
};
|
|
|
|
struct memory_block;
|
|
extern struct node *node_devices[];
|
|
typedef void (*node_registration_func_t)(struct node *);
|
|
|
|
#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
|
|
extern int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages);
|
|
#else
|
|
static inline int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
extern void unregister_node(struct node *node);
|
|
#ifdef CONFIG_NUMA
|
|
/* Core of the node registration - only memory hotplug should use this */
|
|
extern int __register_one_node(int nid);
|
|
|
|
/* Registers an online node */
|
|
static inline int register_one_node(int nid)
|
|
{
|
|
int error = 0;
|
|
|
|
if (node_online(nid)) {
|
|
struct pglist_data *pgdat = NODE_DATA(nid);
|
|
|
|
error = __register_one_node(nid);
|
|
if (error)
|
|
return error;
|
|
/* link memory sections under this node */
|
|
error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages);
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
extern void unregister_one_node(int nid);
|
|
extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
|
|
extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
|
|
extern int register_mem_sect_under_node(struct memory_block *mem_blk,
|
|
int nid);
|
|
extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
|
|
unsigned long phys_index);
|
|
|
|
#ifdef CONFIG_HUGETLBFS
|
|
extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
|
|
node_registration_func_t unregister);
|
|
#endif
|
|
#else
|
|
static inline int __register_one_node(int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int register_one_node(int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int unregister_one_node(int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int register_cpu_under_node(unsigned int cpu, unsigned int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
|
|
int nid)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
|
|
unsigned long phys_index)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void register_hugetlbfs_with_node(node_registration_func_t reg,
|
|
node_registration_func_t unreg)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#define to_node(device) container_of(device, struct node, dev)
|
|
|
|
#endif /* _LINUX_NODE_H_ */
|