Skip to content

Commit

Permalink
cpu/mem hotplug: enable CPUs online before local memory online
Browse files Browse the repository at this point in the history
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.

[[email protected]: remove unneeded export]
[[email protected]: coding-style fixes]
Signed-off-by: minskey guo<[email protected]>
Cc: Minchan Kim <[email protected]>
Cc: Yasunori Goto <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: Tejun Heo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
minskey guo authored and torvalds committed May 25, 2010
1 parent 8b25c6d commit cf23422
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/linux/memory_hotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
25 changes: 25 additions & 0 deletions kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
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);
Expand All @@ -336,6 +342,25 @@ 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) {
Expand Down
23 changes: 23 additions & 0 deletions mm/memory_hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,29 @@ 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;
}

/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
int __ref add_memory(int nid, u64 start, u64 size)
{
Expand Down

0 comments on commit cf23422

Please sign in to comment.