path: root/kernel/cpu.c
diff options
authorminskey guo <chaohong_guo@linux.intel.com>2010-05-24 14:32:41 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 08:07:00 -0700
commitcf23422b9d76215316855253da491d4c9f294372 (patch)
tree5663d2519d83d830d24dffdf2571d58d3e55d3f6 /kernel/cpu.c
parent8b25c6d2231b978ccce9c401e771932bde79aa9f (diff)
cpu/mem hotplug: enable CPUs online before local memory online
Enable 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. [akpm@linux-foundation.org: remove unneeded export] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: minskey guo<chaohong.guo@intel.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cpu.c')
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 54577757477..a3fbcc0a0ab 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -326,6 +326,12 @@ out_notify:
int __cpuinit cpu_up(unsigned int cpu)
int err = 0;
+ int nid;
+ pg_data_t *pgdat;
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);
@@ -336,6 +342,25 @@ int __cpuinit cpu_up(unsigned int cpu)
return -EINVAL;
+ 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();
if (cpu_hotplug_disabled) {