diff options
author | Andi Kleen <ak@suse.de> | 2006-03-25 10:31:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 12:10:56 -0500 |
commit | 267b48014a5c0c2ae90b04dad5d95ceb903365a6 (patch) | |
tree | 95f5475b7b7f6e5b4fd023f51fb2fa826d95a754 /arch/x86_64/mm/numa.c | |
parent | bd6633476922b7b51227f7f704c2546e763ae5ed (diff) |
[PATCH] x86_64: Try to allocate node memmap near the end of node
This fixes problems with very large nodes (over 128GB) filling up all of
the first 4GB with their mem_map and not leaving enough space for the
swiotlb.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/mm/numa.c')
-rw-r--r-- | arch/x86_64/mm/numa.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index e4b62753a19a..07471a3eb190 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -149,7 +149,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
149 | /* Initialize final allocator for a zone */ | 149 | /* Initialize final allocator for a zone */ |
150 | void __init setup_node_zones(int nodeid) | 150 | void __init setup_node_zones(int nodeid) |
151 | { | 151 | { |
152 | unsigned long start_pfn, end_pfn; | 152 | unsigned long start_pfn, end_pfn, memmapsize, limit; |
153 | unsigned long zones[MAX_NR_ZONES]; | 153 | unsigned long zones[MAX_NR_ZONES]; |
154 | unsigned long holes[MAX_NR_ZONES]; | 154 | unsigned long holes[MAX_NR_ZONES]; |
155 | 155 | ||
@@ -159,6 +159,16 @@ void __init setup_node_zones(int nodeid) | |||
159 | Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n", | 159 | Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n", |
160 | nodeid, start_pfn, end_pfn); | 160 | nodeid, start_pfn, end_pfn); |
161 | 161 | ||
162 | /* Try to allocate mem_map at end to not fill up precious <4GB | ||
163 | memory. */ | ||
164 | memmapsize = sizeof(struct page) * (end_pfn-start_pfn); | ||
165 | limit = end_pfn << PAGE_SHIFT; | ||
166 | NODE_DATA(nodeid)->node_mem_map = | ||
167 | __alloc_bootmem_core(NODE_DATA(nodeid)->bdata, | ||
168 | memmapsize, SMP_CACHE_BYTES, | ||
169 | round_down(limit - memmapsize, PAGE_SIZE), | ||
170 | limit); | ||
171 | |||
162 | size_zones(zones, holes, start_pfn, end_pfn); | 172 | size_zones(zones, holes, start_pfn, end_pfn); |
163 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, | 173 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, |
164 | start_pfn, holes); | 174 | start_pfn, holes); |