diff options
author | Andy Whitcroft <apw@shadowen.org> | 2007-08-22 17:01:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-22 22:52:44 -0400 |
commit | 85770ffe4f0cdd4396b17f14762adc25a571a348 (patch) | |
tree | 23f69f720e53cee67632b04c1754c3a7a64dab72 /mm | |
parent | df068464169a84a6a66c05d140f43a46d5eb6176 (diff) |
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 89689ae7f95995723fbcd5c116c47933a3bb8b13
[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>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/sparse.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index 3047bf06c1f3..239f5a720d38 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -41,6 +41,15 @@ int page_to_nid(struct page *page) | |||
41 | return section_to_node_table[page_to_section(page)]; | 41 | return section_to_node_table[page_to_section(page)]; |
42 | } | 42 | } |
43 | EXPORT_SYMBOL(page_to_nid); | 43 | EXPORT_SYMBOL(page_to_nid); |
44 | |||
45 | static void set_section_nid(unsigned long section_nr, int nid) | ||
46 | { | ||
47 | section_to_node_table[section_nr] = nid; | ||
48 | } | ||
49 | #else /* !NODE_NOT_IN_PAGE_FLAGS */ | ||
50 | static inline void set_section_nid(unsigned long section_nr, int nid) | ||
51 | { | ||
52 | } | ||
44 | #endif | 53 | #endif |
45 | 54 | ||
46 | #ifdef CONFIG_SPARSEMEM_EXTREME | 55 | #ifdef CONFIG_SPARSEMEM_EXTREME |
@@ -68,10 +77,6 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid) | |||
68 | struct mem_section *section; | 77 | struct mem_section *section; |
69 | int ret = 0; | 78 | int ret = 0; |
70 | 79 | ||
71 | #ifdef NODE_NOT_IN_PAGE_FLAGS | ||
72 | section_to_node_table[section_nr] = nid; | ||
73 | #endif | ||
74 | |||
75 | if (mem_section[root]) | 80 | if (mem_section[root]) |
76 | return -EEXIST; | 81 | return -EEXIST; |
77 | 82 | ||
@@ -148,6 +153,7 @@ void __init memory_present(int nid, unsigned long start, unsigned long end) | |||
148 | struct mem_section *ms; | 153 | struct mem_section *ms; |
149 | 154 | ||
150 | sparse_index_init(section, nid); | 155 | sparse_index_init(section, nid); |
156 | set_section_nid(section, nid); | ||
151 | 157 | ||
152 | ms = __nr_to_section(section); | 158 | ms = __nr_to_section(section); |
153 | if (!ms->section_mem_map) | 159 | if (!ms->section_mem_map) |