Index: linux-2.6.18-mm3/arch/ia64/mm/discontig.c =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/mm/discontig.c 2006-10-05 21:11:42.000000000 -0500 +++ linux-2.6.18-mm3/arch/ia64/mm/discontig.c 2006-10-05 22:37:02.356118482 -0500 @@ -414,37 +414,25 @@ static void __init memory_less_nodes(voi return; } -#ifdef CONFIG_SPARSEMEM /** - * register_sparse_mem - notify SPARSEMEM that this memory range exists. + * register_memory - notify the kernel that we need page strurct for this + * memory range. * @start: physical start of range * @end: physical end of range * @arg: unused * * Simply calls SPARSEMEM to register memory section(s). */ -static int __init register_sparse_mem(unsigned long start, unsigned long end, +static int __init register_memory(unsigned long start, unsigned long end, void *arg) { - int nid; - - start = __pa(start) >> PAGE_SHIFT; - end = __pa(end) >> PAGE_SHIFT; - nid = early_pfn_to_nid(start); - memory_present(nid, start, end); + memory_present(paddr_to_nid(__pa(start)), + __pa(start) >> PAGE_SHIFT, + __pa(end) >> PAGE_SHIFT); return 0; } -static void __init arch_sparse_init(void) -{ - efi_memmap_walk(register_sparse_mem, NULL); - sparse_init(); -} -#else -#define arch_sparse_init() do {} while (0) -#endif - /** * find_memory - walk the EFI memory map and setup the bootmem allocator * @@ -688,14 +676,14 @@ void __init paging_init(void) int node; unsigned long max_zone_pfns[MAX_NR_ZONES]; - arch_sparse_init(); - + /* + * Why are me registering all of memory? We should only be registering + * memory the kernel will manage later. + */ + efi_memmap_walk(register_memory, NULL); + sparse_init(); efi_memmap_walk(filter_rsvd_memory, count_node_pages); -#ifdef CONFIG_VIRTUAL_MEM_MAP - efi_memmap_walk(create_mem_map_page_table, NULL); -#endif - for_each_online_node(node) { num_physpages += mem_data[node].num_physpages; pfn_offset = mem_data[node].min_pfn; Index: linux-2.6.18-mm3/arch/ia64/mm/init.c =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/mm/init.c 2006-10-05 17:16:03.000000000 -0500 +++ linux-2.6.18-mm3/arch/ia64/mm/init.c 2006-10-05 22:22:51.450965598 -0500 @@ -464,16 +464,6 @@ retry_pte: return hole_next_pfn - pgdat->node_start_pfn; } -int __init -create_mem_map_page_table (u64 start, u64 end, void *arg) -{ - populate_virtual_memmap(paddr_to_nid(__pa(start)), - __pa(start) >> PAGE_SHIFT, - __pa(end) >> PAGE_SHIFT); - - return 0; -} - struct memmap_init_callback_data { struct page *start; struct page *end; Index: linux-2.6.18-mm3/include/linux/bootmem.h =================================================================== --- linux-2.6.18-mm3.orig/include/linux/bootmem.h 2006-10-05 13:29:48.000000000 -0500 +++ linux-2.6.18-mm3/include/linux/bootmem.h 2006-10-05 22:16:09.974316542 -0500 @@ -132,6 +132,4 @@ extern void *alloc_large_system_hash(con #endif extern int hashdist; /* Distribute hashes across NUMA nodes? */ -extern void populate_virtual_memmap(int nid, unsigned long start_pfn, - unsigned long end_pfn); #endif /* _LINUX_BOOTMEM_H */ Index: linux-2.6.18-mm3/include/linux/mmzone.h =================================================================== --- linux-2.6.18-mm3.orig/include/linux/mmzone.h 2006-10-05 22:06:06.000000000 -0500 +++ linux-2.6.18-mm3/include/linux/mmzone.h 2006-10-05 22:16:28.817721436 -0500 @@ -351,6 +351,7 @@ struct node_active_region { #define max_mapnr (VIRTUAL_MEM_MAP_SIZE / sizeof(struct page *) - ARCH_PFN_OFFSET) #endif extern int __pfn_valid(unsigned long pfn); +extern void populate_virtual_memmap(int nid, unsigned long address); #else extern unsigned long max_mapnr; extern struct page *mem_map; Index: linux-2.6.18-mm3/mm/memory.c =================================================================== --- linux-2.6.18-mm3.orig/mm/memory.c 2006-10-05 20:44:49.000000000 -0500 +++ linux-2.6.18-mm3/mm/memory.c 2006-10-05 22:15:43.958424624 -0500 @@ -113,6 +113,22 @@ int __pfn_valid (unsigned long pfn) return result; } EXPORT_SYMBOL(__pfn_valid); + +void memory_present(int nid, unsigned long start_pfn, unsigned long end_pfn) +{ + unsigned long start, end, addr; + + /* Align start and end to the next MAX_ORDER boundary */ + start_pfn &= ~(MAX_ORDER_NR_PAGES - 1); + end_pfn = ALIGN(end_pfn, MAX_ORDER_NR_PAGES); + + /* Align start and end to the next VMEMMAP_SIZE boundary */ + start = __pa(pfn_to_page(start_pfn)) & ~(VMEMMAP_PAGE_SIZE - 1); + end = ALIGN(__pa(pfn_to_page(end_pfn)), VMEMMAP_PAGE_SIZE); + + for (addr = start; addr < end; addr += VMEMMAP_PAGE_SIZE) + populate_virtual_memmap(nid, addr); +} #endif unsigned long num_physpages; Index: linux-2.6.18-mm3/mm/page_alloc.c =================================================================== --- linux-2.6.18-mm3.orig/mm/page_alloc.c 2006-10-05 21:38:45.000000000 -0500 +++ linux-2.6.18-mm3/mm/page_alloc.c 2006-10-05 22:21:46.912253251 -0500 @@ -154,7 +154,7 @@ static int page_outside_zone_boundaries( static int page_is_consistent(struct zone *zone, struct page *page) { -#ifdef CONFIG_HOLES_IN_ZONE +#if defined(CONFIG_HOLES_IN_ZONE) && !defined(CONFIG_VIRTUAL_MEM_MAP) if (!pfn_valid(page_to_pfn(page))) return 0; #endif @@ -359,7 +359,7 @@ __find_combined_index(unsigned long page static inline int page_is_buddy(struct page *page, struct page *buddy, int order) { -#ifdef CONFIG_HOLES_IN_ZONE +#if defined(CONFIG_HOLES_IN_ZONE) && !defined(CONFIG_VIRTUAL_MEM_MAP) if (!pfn_valid(page_to_pfn(buddy))) return 0; #endif