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 89689ae7f9
[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: Andy Whitcroft <apw@shadowen.org>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
df06846416
commit
85770ffe4f
14
mm/sparse.c
14
mm/sparse.c
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
||||||
|
Reference in New Issue
Block a user