Commit f52407ce authored by Shaohua Li's avatar Shaohua Li Committed by Linus Torvalds

memory hotplug: alloc page from other node in memory online

To initialize hotadded node, some pages are allocated.  At that time, the
node hasn't memory, this makes the allocation always fail.  In such case,
let's allocate pages from other nodes.
Signed-off-by: default avatarShaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarYakui Zhao <yakui.zhao@intel.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8e7e40d9
...@@ -116,10 +116,16 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn) ...@@ -116,10 +116,16 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn)
nid = page_to_nid(pfn_to_page(pfn)); nid = page_to_nid(pfn_to_page(pfn));
table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION;
VM_BUG_ON(!slab_is_available()); VM_BUG_ON(!slab_is_available());
if (node_state(nid, N_HIGH_MEMORY)) {
base = kmalloc_node(table_size, base = kmalloc_node(table_size,
GFP_KERNEL | __GFP_NOWARN, nid); GFP_KERNEL | __GFP_NOWARN, nid);
if (!base) if (!base)
base = vmalloc_node(table_size, nid); base = vmalloc_node(table_size, nid);
} else {
base = kmalloc(table_size, GFP_KERNEL | __GFP_NOWARN);
if (!base)
base = vmalloc(table_size);
}
} else { } else {
/* /*
* We don't have to allocate page_cgroup again, but * We don't have to allocate page_cgroup again, but
......
...@@ -48,8 +48,14 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node) ...@@ -48,8 +48,14 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
{ {
/* If the main allocator is up use that, fallback to bootmem. */ /* If the main allocator is up use that, fallback to bootmem. */
if (slab_is_available()) { if (slab_is_available()) {
struct page *page = alloc_pages_node(node, struct page *page;
if (node_state(node, N_HIGH_MEMORY))
page = alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO, get_order(size)); GFP_KERNEL | __GFP_ZERO, get_order(size));
else
page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
get_order(size));
if (page) if (page)
return page_address(page); return page_address(page);
return NULL; return NULL;
......
...@@ -62,9 +62,12 @@ static struct mem_section noinline __init_refok *sparse_index_alloc(int nid) ...@@ -62,9 +62,12 @@ static struct mem_section noinline __init_refok *sparse_index_alloc(int nid)
unsigned long array_size = SECTIONS_PER_ROOT * unsigned long array_size = SECTIONS_PER_ROOT *
sizeof(struct mem_section); sizeof(struct mem_section);
if (slab_is_available()) if (slab_is_available()) {
if (node_state(nid, N_HIGH_MEMORY))
section = kmalloc_node(array_size, GFP_KERNEL, nid); section = kmalloc_node(array_size, GFP_KERNEL, nid);
else else
section = kmalloc(array_size, GFP_KERNEL);
} else
section = alloc_bootmem_node(NODE_DATA(nid), array_size); section = alloc_bootmem_node(NODE_DATA(nid), array_size);
if (section) if (section)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment