Skip to content

Commit f52407c

Browse files
Shaohua Litorvalds
authored andcommitted
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: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Yakui Zhao <yakui.zhao@intel.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Christoph Lameter <cl@linux-foundation.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 8e7e40d commit f52407c

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

mm/page_cgroup.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,16 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn)
116116
nid = page_to_nid(pfn_to_page(pfn));
117117
table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION;
118118
VM_BUG_ON(!slab_is_available());
119-
base = kmalloc_node(table_size,
119+
if (node_state(nid, N_HIGH_MEMORY)) {
120+
base = kmalloc_node(table_size,
120121
GFP_KERNEL | __GFP_NOWARN, nid);
121-
if (!base)
122-
base = vmalloc_node(table_size, nid);
122+
if (!base)
123+
base = vmalloc_node(table_size, nid);
124+
} else {
125+
base = kmalloc(table_size, GFP_KERNEL | __GFP_NOWARN);
126+
if (!base)
127+
base = vmalloc(table_size);
128+
}
123129
} else {
124130
/*
125131
* We don't have to allocate page_cgroup again, but

mm/sparse-vmemmap.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
4848
{
4949
/* If the main allocator is up use that, fallback to bootmem. */
5050
if (slab_is_available()) {
51-
struct page *page = alloc_pages_node(node,
51+
struct page *page;
52+
53+
if (node_state(node, N_HIGH_MEMORY))
54+
page = alloc_pages_node(node,
5255
GFP_KERNEL | __GFP_ZERO, get_order(size));
56+
else
57+
page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
58+
get_order(size));
5359
if (page)
5460
return page_address(page);
5561
return NULL;

mm/sparse.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ static struct mem_section noinline __init_refok *sparse_index_alloc(int nid)
6262
unsigned long array_size = SECTIONS_PER_ROOT *
6363
sizeof(struct mem_section);
6464

65-
if (slab_is_available())
66-
section = kmalloc_node(array_size, GFP_KERNEL, nid);
67-
else
65+
if (slab_is_available()) {
66+
if (node_state(nid, N_HIGH_MEMORY))
67+
section = kmalloc_node(array_size, GFP_KERNEL, nid);
68+
else
69+
section = kmalloc(array_size, GFP_KERNEL);
70+
} else
6871
section = alloc_bootmem_node(NODE_DATA(nid), array_size);
6972

7073
if (section)

0 commit comments

Comments
 (0)