Skip to content

Commit

Permalink
[PATCH] x86_64: Try to allocate node memmap near the end of node
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Mar 25, 2006
1 parent bd66334 commit 267b480
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
12 changes: 11 additions & 1 deletion arch/x86_64/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
/* Initialize final allocator for a zone */
void __init setup_node_zones(int nodeid)
{
unsigned long start_pfn, end_pfn;
unsigned long start_pfn, end_pfn, memmapsize, limit;
unsigned long zones[MAX_NR_ZONES];
unsigned long holes[MAX_NR_ZONES];

Expand All @@ -159,6 +159,16 @@ void __init setup_node_zones(int nodeid)
Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n",
nodeid, start_pfn, end_pfn);

/* Try to allocate mem_map at end to not fill up precious <4GB
memory. */
memmapsize = sizeof(struct page) * (end_pfn-start_pfn);
limit = end_pfn << PAGE_SHIFT;
NODE_DATA(nodeid)->node_mem_map =
__alloc_bootmem_core(NODE_DATA(nodeid)->bdata,
memmapsize, SMP_CACHE_BYTES,
round_down(limit - memmapsize, PAGE_SIZE),
limit);

size_zones(zones, holes, start_pfn, end_pfn);
free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
start_pfn, holes);
Expand Down
3 changes: 3 additions & 0 deletions include/linux/bootmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ extern void * __init __alloc_bootmem_low_node(pg_data_t *pgdat,
unsigned long size,
unsigned long align,
unsigned long goal);
extern void * __init __alloc_bootmem_core(struct bootmem_data *bdata,
unsigned long size, unsigned long align, unsigned long goal,
unsigned long limit);
#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
#define alloc_bootmem(x) \
Expand Down
2 changes: 1 addition & 1 deletion mm/bootmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
*
* NOTE: This function is _not_ reentrant.
*/
static void * __init
void * __init
__alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
unsigned long align, unsigned long goal, unsigned long limit)
{
Expand Down

0 comments on commit 267b480

Please sign in to comment.