Commit 85770ffe authored by Andy Whitcroft's avatar Andy Whitcroft Committed by Linus Torvalds

sparsemem: ensure we initialise the node mapping for SPARSEMEM_STATIC

Booting SPARSEMEM on NUMA systems trips a BUG in page_alloc.c:

	Initializing HighMem for node 0 (00038000:00100000)
	Initializing HighMem for node 1 (00100000:001ffe00)
	------------[ cut here ]------------
	kernel BUG at /home/apw/git/linux-2.6/mm/page_alloc.c:456!
	[...]

This occurs because the section to node id mapping is not being
setup correctly during init under SPARSEMEM_STATIC, leading to an
attempt to free pages from all nodes into the zones on node 0.

When the zone_table[] was removed in the following commit, a new
section to node mapping table was introduced:

    commit 89689ae7
    [PATCH] Get rid of zone_table[]

That conversion inadvertantly only initialised the node mapping in
SPARSEMEM_EXTREME.  Ensure we initialise the node mapping in
SPARSEMEM_STATIC.

[akpm@linux-foundation.org: make the stubs static inline]
Signed-off-by: default avatarAndy Whitcroft <apw@shadowen.org>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent df068464
...@@ -41,6 +41,15 @@ int page_to_nid(struct page *page) ...@@ -41,6 +41,15 @@ int page_to_nid(struct page *page)
return section_to_node_table[page_to_section(page)]; return section_to_node_table[page_to_section(page)];
} }
EXPORT_SYMBOL(page_to_nid); EXPORT_SYMBOL(page_to_nid);
static void set_section_nid(unsigned long section_nr, int nid)
{
section_to_node_table[section_nr] = nid;
}
#else /* !NODE_NOT_IN_PAGE_FLAGS */
static inline void set_section_nid(unsigned long section_nr, int nid)
{
}
#endif #endif
#ifdef CONFIG_SPARSEMEM_EXTREME #ifdef CONFIG_SPARSEMEM_EXTREME
...@@ -68,10 +77,6 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid) ...@@ -68,10 +77,6 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid)
struct mem_section *section; struct mem_section *section;
int ret = 0; int ret = 0;
#ifdef NODE_NOT_IN_PAGE_FLAGS
section_to_node_table[section_nr] = nid;
#endif
if (mem_section[root]) if (mem_section[root])
return -EEXIST; return -EEXIST;
...@@ -148,6 +153,7 @@ void __init memory_present(int nid, unsigned long start, unsigned long end) ...@@ -148,6 +153,7 @@ void __init memory_present(int nid, unsigned long start, unsigned long end)
struct mem_section *ms; struct mem_section *ms;
sparse_index_init(section, nid); sparse_index_init(section, nid);
set_section_nid(section, nid);
ms = __nr_to_section(section); ms = __nr_to_section(section);
if (!ms->section_mem_map) if (!ms->section_mem_map)
......
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