VMMAP: Initialize virtual memmap properly in memmap_init_zone If we have a VIRTUAL_MEM_MAP then memmap_init_zone needs to consider the page boundaries of the virtual memory map. This also introduces VMEMMAP_PAGE_SIZE which defines the page size of the pages used for the Virtual memmap. Signed-off-by: Christoph Lameter Index: linux-2.6.18-mm3/mm/page_alloc.c =================================================================== --- linux-2.6.18-mm3.orig/mm/page_alloc.c 2006-10-04 00:35:57.131054837 -0500 +++ linux-2.6.18-mm3/mm/page_alloc.c 2006-10-04 01:34:13.100258531 -0500 @@ -1772,6 +1772,23 @@ void __meminit memmap_init_zone(unsigned unsigned long end_pfn = start_pfn + size; unsigned long pfn; +#ifdef CONFIG_VIRTUAL_MEM_MAP + /* + * We have to initialize "out of bounds" struct page elements that + * fit completely on the same pages that were allocated for the + * "in bounds" elements because they may be referenced later (and + * found to be "reserved"). + */ + start_pfn -= + ((unsigned long) pfn_to_page(start_pfn)) & (VMEMMAP_PAGE_SIZE - 1) + / sizeof(struct page); + + end_pfn += + (ALIGN(((unsigned long) pfn_to_page(end_pfn)), VMEMMAP_PAGE_SIZE) - + (unsigned long) (pfn_to_page(end_pfn))) + / sizeof(struct page); + +#endif for (pfn = start_pfn; pfn < end_pfn; pfn++) { if (!early_pfn_valid(pfn)) continue; Index: linux-2.6.18-mm3/arch/ia64/mm/init.c =================================================================== --- linux-2.6.18-mm3.orig/arch/ia64/mm/init.c 2006-10-04 01:17:44.914767745 -0500 +++ linux-2.6.18-mm3/arch/ia64/mm/init.c 2006-10-04 01:34:13.129557898 -0500 @@ -530,15 +530,6 @@ virtual_memmap_init (u64 start, u64 end, if (map_end > args->end) map_end = args->end; - /* - * We have to initialize "out of bounds" struct page elements that fit completely - * on the same pages that were allocated for the "in bounds" elements because they - * may be referenced later (and found to be "reserved"). - */ - map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) / sizeof(struct page); - map_end += ((PAGE_ALIGN((unsigned long) map_end) - (unsigned long) map_end) - / sizeof(struct page)); - if (map_start < map_end) memmap_init_zone((unsigned long)(map_end - map_start), args->nid, args->zone, page_to_pfn(map_start));