diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 1336da8bdee125f5b0ba227360d89c4709264323..1ad5111aec381d7042648c0a871f2707181f3400 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -761,3 +761,9 @@ int in_gate_area_no_task(unsigned long addr) { return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); } + +void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) +{ + return __alloc_bootmem_core(pgdat->bdata, size, + SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0); +} diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 0365ec9fc0c9248422801fe71b232d1188a12972..c83534ee1e796c46b2cc47c129ad3924cedbeb20 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -59,6 +59,7 @@ extern void *__alloc_bootmem_core(struct bootmem_data *bdata, unsigned long align, unsigned long goal, unsigned long limit); +extern void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size); #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE extern void reserve_bootmem(unsigned long addr, unsigned long size); diff --git a/mm/sparse.c b/mm/sparse.c index 1302f8348d51c8dbc10d104c333eeea3e01a6f1a..545e4d3afcdff14877204b270bf6e671c33d5509 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -209,6 +209,12 @@ static int __meminit sparse_init_one_section(struct mem_section *ms, return 1; } +__attribute__((weak)) +void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) +{ + return NULL; +} + static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) { struct page *map; @@ -219,6 +225,11 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) if (map) return map; + map = alloc_bootmem_high_node(NODE_DATA(nid), + sizeof(struct page) * PAGES_PER_SECTION); + if (map) + return map; + map = alloc_bootmem_node(NODE_DATA(nid), sizeof(struct page) * PAGES_PER_SECTION); if (map)