[PATCH] Align the node_mem_map endpoints to a MAX_ORDER boundary
Andy added code to buddy allocator which does not require the zone's endpoints to be aligned to MAX_ORDER. An issue is that the buddy allocator requires the node_mem_map's endpoints to be MAX_ORDER aligned. Otherwise __page_find_buddy could compute a buddy not in node_mem_map for partial MAX_ORDER regions at zone's endpoints. page_is_buddy will detect that these pages at endpoints are not PG_buddy (they were zeroed out by bootmem allocator and not part of zone). Of course the negative here is we could waste a little memory but the positive is eliminating all the old checks for zone boundary conditions. SPARSEMEM won't encounter this issue because of MAX_ORDER size constraint when SPARSEMEM is configured. ia64 VIRTUAL_MEM_MAP doesn't need the logic either because the holes and endpoints are handled differently. This leaves checking alloc_remap and other arches which privately allocate for node_mem_map. Signed-off-by: Bob Picco <bob.picco@hp.com> Acked-by: Mel Gorman <mel@csn.ul.ie> Cc: Dave Hansen <haveblue@us.ibm.com> Cc: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
ae57a85642
commit
e984bb43f7
2 changed files with 12 additions and 3 deletions
|
@ -22,6 +22,7 @@
|
|||
#else
|
||||
#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
|
||||
#endif
|
||||
#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
|
||||
|
||||
struct free_area {
|
||||
struct list_head free_list;
|
||||
|
|
|
@ -2125,14 +2125,22 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
|
|||
#ifdef CONFIG_FLAT_NODE_MEM_MAP
|
||||
/* ia64 gets its own node_mem_map, before this, without bootmem */
|
||||
if (!pgdat->node_mem_map) {
|
||||
unsigned long size;
|
||||
unsigned long size, start, end;
|
||||
struct page *map;
|
||||
|
||||
size = (pgdat->node_spanned_pages + 1) * sizeof(struct page);
|
||||
/*
|
||||
* The zone's endpoints aren't required to be MAX_ORDER
|
||||
* aligned but the node_mem_map endpoints must be in order
|
||||
* for the buddy allocator to function correctly.
|
||||
*/
|
||||
start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
|
||||
end = pgdat->node_start_pfn + pgdat->node_spanned_pages;
|
||||
end = ALIGN(end, MAX_ORDER_NR_PAGES);
|
||||
size = (end - start) * sizeof(struct page);
|
||||
map = alloc_remap(pgdat->node_id, size);
|
||||
if (!map)
|
||||
map = alloc_bootmem_node(pgdat, size);
|
||||
pgdat->node_mem_map = map;
|
||||
pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
|
||||
}
|
||||
#ifdef CONFIG_FLATMEM
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue