permit to online CPUs before local memory comes online
Subsystems (4)
PATCH 1/1 permit to online CPUs before local memory comes online
This patch enables users to online CPUs even if the CPUs belongs to a numa node which doesn't have onlined local memory.
The zonlists(pg_data_t.node_zonelists[]) of a numa node are created either in system boot/init period, or at the time of local memory online. For a numa node without onlined local memory, its zonelists are not initialized at present. As a result, any memory allocation operations executed by CPUs within this node will fail. In fact, an out-of-memory error is triggered when attempt to online CPUs before memory comes to online.
This patch tries to create zonelists for such numa nodes, so that the memory allocation for this node can be fallback'ed to other nodes.
--- include/linux/memory_hotplug.h | 1 + kernel/cpu.c | 26 ++++++++++++++++++++++++++ mm/memory_hotplug.c | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 0 deletions(-)
include/linux/memory_hotplug.h +1 -0
@@ -202,6 +202,7 @@ static inline int is_mem_section_removable(unsigned long pfn, }#endif /* CONFIG_MEMORY_HOTREMOVE */ +extern int mem_online_node (int nid);extern int add_memory (int nid,u64 start,u64 size);extern int arch_add_memory (int nid,u64 start,u64 size);extern int remove_memory (u64 start,u64 size);
kernel/cpu.c +26 -0
@@ -335,6 +335,12 @@ out_notify:int __cpuinit cpu_up (unsigned int cpu) {int err =0 ; + +#ifdef CONFIG_MEMORY_HOTPLUG +int nid; +pg_data_t *pgdat; +#endif +if (!cpu_possible (cpu)) {printk (KERN_ERR "can't online cpu %d because it is not " "configured as may-hotadd at boot time\n" , cpu);
@@ -345,6 +351,26 @@ int __cpuinit cpu_up(unsigned int cpu)return -EINVAL ; } +#ifdef CONFIG_MEMORY_HOTPLUG + nid =cpu_to_node (cpu); +if (!node_online (nid)) { + err =mem_online_node (nid); +if (err) +return err; + } + + pgdat =NODE_DATA (nid); +if (!pgdat) { +printk (KERN_ERR +"Can't online cpu %d due to NULL pgdat\n" , cpu); +return -ENOMEM ; + } + +if (pgdat->node_zonelists->_zonerefs->zone ==NULL ) { +build_all_zonelists (); + } +#endif +cpu_maps_update_begin ();if (cpu_hotplug_disabled) {
mm/memory_hotplug.c +25 -0
@@ -482,6 +482,31 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat) } +/* +* called by cpu_up() to online a node without onlined memory. +*/ +int mem_online_node (int nid) +{ +pg_data_t *pgdat; +int ret; + +lock_system_sleep (); + pgdat =hotadd_new_pgdat (nid,0 ); +if (pgdat) { + ret = -ENOMEM ; + goto out; + } +node_set_online (nid); + ret =register_one_node (nid); +BUG_ON (ret); + +out: +unlock_system_sleep (); +return ret; +} +EXPORT_SYMBOL_GPL (mem_online_node); + +/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ int __ref add_memory (int nid,u64 start,u64 size) {
Signature · 1 line
1.6.3.3
Could you please help me review this patch and give me some inputs ? such as, is it acceptable to do that, I mean, online CPUs of a NUMA node without local memory
The patch is against upstream vanilla kernel.
I mis-spelled the mail address of linux-mm when I sent the email for the first time, please forgive me if you receive two copies.
thanks,
-minskey
Quoted 116 lines · minskey
This patch enables users to online CPUs even if the CPUs belongs to a numa node which doesn't have onlined local memory.
The
zonlists(pg_data_t.node_zonelists[])of a numa node are created either in system boot/init period, or at the time of local memory online. For a numa node without onlined local memory, its zonelists are not initialized at present. As a result, any memory allocation operations executed by CPUs within this node will fail. In fact, an out-of-memory error is triggered when attempt to online CPUs before memory comes to online.This patch tries to create zonelists for such numa nodes, so that the memory allocation for this node can be fallback'ed to other nodes.
Signed-off-by minskey guo<[email protected]>--- include/linux/memory_hotplug.h | 1 + kernel/cpu.c | 26 ++++++++++++++++++++++++++ mm/memory_hotplug.c | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 0 deletions(-)include/linux/memory_hotplug.h +1
-0@@ -202,6 +202,7 @@ static inline int is_mem_section_removable(unsigned long pfn, }#endif /* CONFIG_MEMORY_HOTREMOVE */ +extern int mem_online_node (int nid);extern int add_memory (int nid,u64 start,u64 size);extern int arch_add_memory (int nid,u64 start,u64 size);extern int remove_memory (u64 start,u64 size);kernel/cpu.c +26
-0@@ -335,6 +335,12 @@ out_notify:int __cpuinit cpu_up (unsigned int cpu) {int err =0 ; + +#ifdef CONFIG_MEMORY_HOTPLUG +int nid; +pg_data_t *pgdat; +#endif +if (!cpu_possible (cpu)) {printk (KERN_ERR "can't online cpu %d because it is not " "configured as may-hotadd at boot time\n" , cpu);@@ -345,6 +351,26 @@ int __cpuinit cpu_up(unsigned int cpu)return -EINVAL ; } +#ifdef CONFIG_MEMORY_HOTPLUG + nid =cpu_to_node (cpu); +if (!node_online (nid)) { + err =mem_online_node (nid); +if (err) +return err; + } + + pgdat =NODE_DATA (nid); +if (!pgdat) { +printk (KERN_ERR +"Can't online cpu %d due to NULL pgdat\n" , cpu); +return -ENOMEM ; + } + +if (pgdat->node_zonelists->_zonerefs->zone ==NULL ) { +build_all_zonelists (); + } +#endif +cpu_maps_update_begin ();if (cpu_hotplug_disabled) {mm/memory_hotplug.c +25
-0@@ -482,6 +482,31 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat) } +/* +* called by cpu_up() to online a node without onlined memory. +*/ +int mem_online_node (int nid) +{ +pg_data_t *pgdat; +int ret; + +lock_system_sleep (); + pgdat =hotadd_new_pgdat (nid,0 ); +if (pgdat) { + ret = -ENOMEM ; + goto out; + } +node_set_online (nid); + ret =register_one_node (nid); +BUG_ON (ret); + +out: +unlock_system_sleep (); +return ret; +} +EXPORT_SYMBOL_GPL (mem_online_node); + +/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ int __ref add_memory (int nid,u64 start,u64 size) {