Signed-off-by: Dave Hansen --- memhotplug-dave/arch/alpha/mm/numa.c | 2 memhotplug-dave/arch/arm/mm/init.c | 6 -- memhotplug-dave/arch/arm26/mm/init.c | 4 - memhotplug-dave/arch/cris/arch-v10/mm/init.c | 3 - memhotplug-dave/arch/i386/mm/discontig.c | 11 +--- memhotplug-dave/arch/ia64/mm/contig.c | 7 +-- memhotplug-dave/arch/ia64/mm/discontig.c | 4 - memhotplug-dave/arch/ia64/mm/init.c | 8 ++- memhotplug-dave/arch/mips/sgi-ip27/ip27-memory.c | 2 memhotplug-dave/arch/parisc/mm/init.c | 2 memhotplug-dave/arch/ppc64/mm/init.c | 3 - memhotplug-dave/arch/ppc64/mm/numa.c | 12 ----- memhotplug-dave/arch/sh/mm/init.c | 6 -- memhotplug-dave/arch/sh64/mm/init.c | 5 -- memhotplug-dave/arch/sparc/mm/srmmu.c | 3 - memhotplug-dave/arch/sparc/mm/sun4c.c | 3 - memhotplug-dave/arch/sparc64/mm/init.c | 3 - memhotplug-dave/arch/v850/kernel/setup.c | 3 - memhotplug-dave/arch/x86_64/mm/numa.c | 2 memhotplug-dave/include/asm-ia64/pgtable.h | 2 memhotplug-dave/include/linux/mm.h | 5 -- memhotplug-dave/mm/page_alloc.c | 51 ++++++++++++++--------- 22 files changed, 66 insertions(+), 81 deletions(-) diff -puN arch/alpha/mm/numa.c~B-init-no-mem_map arch/alpha/mm/numa.c --- memhotplug/arch/alpha/mm/numa.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/alpha/mm/numa.c Thu Aug 5 19:13:41 2004 @@ -313,7 +313,7 @@ void __init paging_init(void) zones_size[ZONE_DMA] = dma_local_pfn; zones_size[ZONE_NORMAL] = (end_pfn - start_pfn) - dma_local_pfn; } - free_area_init_node(nid, NODE_DATA(nid), NULL, zones_size, start_pfn, NULL); + free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn, NULL); } /* Initialize the kernel's ZERO_PGE. */ diff -puN arch/arm/mm/init.c~B-init-no-mem_map arch/arm/mm/init.c --- memhotplug/arch/arm/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/arm/mm/init.c Thu Aug 5 19:13:41 2004 @@ -502,13 +502,9 @@ void __init paging_init(struct meminfo * */ arch_adjust_zones(node, zone_size, zhole_size); - free_area_init_node(node, pgdat, NULL, zone_size, + free_area_init_node(node, pgdat, zone_size, bdata->node_boot_start >> PAGE_SHIFT, zhole_size); } - -#ifndef CONFIG_DISCONTIGMEM - mem_map = contig_page_data.node_mem_map; -#endif /* * finish off the bad pages once diff -puN arch/arm26/mm/init.c~B-init-no-mem_map arch/arm26/mm/init.c --- memhotplug/arch/arm26/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/arm26/mm/init.c Thu Aug 5 19:13:41 2004 @@ -306,10 +306,8 @@ void __init paging_init(struct meminfo * if (!zone_size[0]) BUG(); - free_area_init_node(0, pgdat, 0, zone_size, + free_area_init_node(0, pgdat, zone_size, bdata->node_boot_start >> PAGE_SHIFT, zhole_size); - - mem_map = NODE_DATA(0)->node_mem_map; /* * finish off the bad pages once diff -puN arch/cris/arch-v10/mm/init.c~B-init-no-mem_map arch/cris/arch-v10/mm/init.c --- memhotplug/arch/cris/arch-v10/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/cris/arch-v10/mm/init.c Thu Aug 5 19:13:41 2004 @@ -183,8 +183,7 @@ paging_init(void) * mem_map page array. */ - free_area_init_node(0, &contig_page_data, 0, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0); - mem_map = contig_page_data.node_mem_map; + free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0); } /* Initialize remaps of some I/O-ports. It is important that this diff -puN arch/i386/mm/discontig.c~B-init-no-mem_map arch/i386/mm/discontig.c --- memhotplug/arch/i386/mm/discontig.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/i386/mm/discontig.c Thu Aug 5 19:13:41 2004 @@ -417,18 +417,15 @@ void __init zone_sizes_init(void) * normal bootmem allocator, but other nodes come from the * remapped KVA area - mbligh */ - if (!nid) - free_area_init_node(nid, NODE_DATA(nid), 0, - zones_size, start, zholes_size); - else { + if (nid) { unsigned long lmem_map; lmem_map = (unsigned long)node_remap_start_vaddr[nid]; lmem_map += sizeof(pg_data_t) + PAGE_SIZE - 1; lmem_map &= PAGE_MASK; - free_area_init_node(nid, NODE_DATA(nid), - (struct page *)lmem_map, zones_size, - start, zholes_size); + NODE_DATA(nid)->node_mem_map = (struct page *)lmem_map; } + free_area_init_node(nid, NODE_DATA(nid), zones_size, + start, zholes_size); } return; } diff -puN arch/ia64/mm/contig.c~B-init-no-mem_map arch/ia64/mm/contig.c --- memhotplug/arch/ia64/mm/contig.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/ia64/mm/contig.c Thu Aug 5 19:13:41 2004 @@ -267,9 +267,8 @@ paging_init (void) efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; - free_area_init_node(0, &contig_page_data, NULL, zones_size, 0, + free_area_init_node(0, &contig_page_data, zones_size, 0, zholes_size); - mem_map = contig_page_data.node_mem_map; } else { unsigned long map_size; @@ -280,10 +279,10 @@ paging_init (void) vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, 0); - free_area_init_node(0, &contig_page_data, vmem_map, zones_size, + NODE_DATA(0)->node_mem_map = vmem_map; + free_area_init_node(0, &contig_page_data, zones_size, 0, zholes_size); - mem_map = contig_page_data.node_mem_map; printk("Virtual mem_map starts at 0x%p\n", mem_map); } #else /* !CONFIG_VIRTUAL_MEM_MAP */ diff -puN arch/ia64/mm/discontig.c~B-init-no-mem_map arch/ia64/mm/discontig.c --- memhotplug/arch/ia64/mm/discontig.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/ia64/mm/discontig.c Thu Aug 5 19:13:41 2004 @@ -665,8 +665,8 @@ void paging_init(void) pfn_offset = mem_data[node].min_pfn; - free_area_init_node(node, NODE_DATA(node), - vmem_map + pfn_offset, zones_size, + NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; + free_area_init_node(node, NODE_DATA(node), zones_size, pfn_offset, zholes_size); } diff -puN arch/ia64/mm/init.c~B-init-no-mem_map arch/ia64/mm/init.c --- memhotplug/arch/ia64/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/ia64/mm/init.c Thu Aug 5 19:13:41 2004 @@ -433,14 +433,16 @@ virtual_memmap_init (u64 start, u64 end, } void -memmap_init (struct page *start, unsigned long size, int nid, - unsigned long zone, unsigned long start_pfn) +memmap_init (unsigned long size, int nid, unsigned long zone, + unsigned long start_pfn) { if (!vmem_map) - memmap_init_zone(start, size, nid, zone, start_pfn); + memmap_init_zone(size, nid, zone, start_pfn); else { + struct page *start; struct memmap_init_callback_data args; + start = pfn_to_page(start_pfn); args.start = start; args.end = start + size; args.nid = nid; diff -puN arch/mips/sgi-ip27/ip27-memory.c~B-init-no-mem_map arch/mips/sgi-ip27/ip27-memory.c --- memhotplug/arch/mips/sgi-ip27/ip27-memory.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/mips/sgi-ip27/ip27-memory.c Thu Aug 5 19:13:41 2004 @@ -225,7 +225,7 @@ void __init paging_init(void) pfn_t end_pfn = node_getmaxclick(node) + 1; zones_size[ZONE_DMA] = end_pfn - start_pfn; - free_area_init_node(node, NODE_DATA(node), NULL, + free_area_init_node(node, NODE_DATA(node), zones_size, start_pfn, NULL); if (end_pfn > max_low_pfn) diff -puN arch/parisc/mm/init.c~B-init-no-mem_map arch/parisc/mm/init.c --- memhotplug/arch/parisc/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/parisc/mm/init.c Thu Aug 5 19:13:41 2004 @@ -761,7 +761,7 @@ void __init paging_init(void) unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0, }; zones_size[ZONE_DMA] = pmem_ranges[i].pages; - free_area_init_node(i,NODE_DATA(i),NULL,zones_size, + free_area_init_node(i,NODE_DATA(i),zones_size, (pmem_ranges[i].start_pfn << PAGE_SHIFT),0); } diff -puN arch/ppc64/mm/init.c~B-init-no-mem_map arch/ppc64/mm/init.c --- memhotplug/arch/ppc64/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/ppc64/mm/init.c Thu Aug 5 19:13:41 2004 @@ -587,9 +587,8 @@ void __init paging_init(void) zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; - free_area_init_node(0, &contig_page_data, NULL, zones_size, + free_area_init_node(0, &contig_page_data, zones_size, __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); - mem_map = contig_page_data.node_mem_map; } #endif /* CONFIG_DISCONTIGMEM */ diff -puN arch/ppc64/mm/numa.c~B-init-no-mem_map arch/ppc64/mm/numa.c --- memhotplug/arch/ppc64/mm/numa.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/ppc64/mm/numa.c Thu Aug 5 19:13:41 2004 @@ -464,17 +464,7 @@ void __init paging_init(void) dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); - /* - * Give this empty node a dummy struct page to avoid - * us from trying to allocate a node local mem_map - * in free_area_init_node (which will fail). - */ - if (!node_data[nid].node_spanned_pages) - node_mem_map = alloc_bootmem(sizeof(struct page)); - else - node_mem_map = NULL; - - free_area_init_node(nid, NODE_DATA(nid), node_mem_map, + free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn, zholes_size); } } diff -puN arch/sh/mm/init.c~B-init-no-mem_map arch/sh/mm/init.c --- memhotplug/arch/sh/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/sh/mm/init.c Thu Aug 5 19:13:41 2004 @@ -215,9 +215,7 @@ void __init paging_init(void) disable_mmu(); #endif - free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START >> PAGE_SHIFT, 0); - /* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/ - mem_map = NODE_DATA(0)->node_mem_map; + free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); #ifdef CONFIG_DISCONTIGMEM /* @@ -225,7 +223,7 @@ void __init paging_init(void) */ zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT; zones_size[ZONE_NORMAL] = 0; - free_area_init_node(1, NODE_DATA(1), 0, zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0); + free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0); #endif } diff -puN arch/sh64/mm/init.c~B-init-no-mem_map arch/sh64/mm/init.c --- memhotplug/arch/sh64/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/sh64/mm/init.c Thu Aug 5 19:13:41 2004 @@ -123,10 +123,7 @@ void __init paging_init(void) */ zones_size[ZONE_DMA] = MAX_LOW_PFN - START_PFN; - free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START >> PAGE_SHIFT, 0); - - /* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/ - mem_map = NODE_DATA(0)->node_mem_map; + free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); } void __init mem_init(void) diff -puN arch/sparc/mm/srmmu.c~B-init-no-mem_map arch/sparc/mm/srmmu.c --- memhotplug/arch/sparc/mm/srmmu.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/sparc/mm/srmmu.c Thu Aug 5 19:13:41 2004 @@ -1341,9 +1341,8 @@ void __init srmmu_paging_init(void) zones_size[ZONE_HIGHMEM] = npages; zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); - free_area_init_node(0, &contig_page_data, NULL, zones_size, + free_area_init_node(0, &contig_page_data, zones_size, pfn_base, zholes_size); - mem_map = contig_page_data.node_mem_map; } } diff -puN arch/sparc/mm/sun4c.c~B-init-no-mem_map arch/sparc/mm/sun4c.c --- memhotplug/arch/sparc/mm/sun4c.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/sparc/mm/sun4c.c Thu Aug 5 19:13:41 2004 @@ -2114,9 +2114,8 @@ void __init sun4c_paging_init(void) zones_size[ZONE_HIGHMEM] = npages; zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); - free_area_init_node(0, &contig_page_data, NULL, zones_size, + free_area_init_node(0, &contig_page_data, zones_size, pfn_base, zholes_size); - mem_map = contig_page_data.node_mem_map; } cnt = 0; diff -puN arch/sparc64/mm/init.c~B-init-no-mem_map arch/sparc64/mm/init.c --- memhotplug/arch/sparc64/mm/init.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/sparc64/mm/init.c Thu Aug 5 19:13:41 2004 @@ -1585,9 +1585,8 @@ void __init paging_init(void) zones_size[ZONE_DMA] = npages; zholes_size[ZONE_DMA] = npages - pages_avail; - free_area_init_node(0, &contig_page_data, NULL, zones_size, + free_area_init_node(0, &contig_page_data, zones_size, phys_base >> PAGE_SHIFT, zholes_size); - mem_map = contig_page_data.node_mem_map; } device_scan(); diff -puN arch/x86_64/mm/numa.c~B-init-no-mem_map arch/x86_64/mm/numa.c --- memhotplug/arch/x86_64/mm/numa.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/x86_64/mm/numa.c Thu Aug 5 19:13:41 2004 @@ -136,7 +136,7 @@ void __init setup_node_zones(int nodeid) zones[ZONE_NORMAL] = end_pfn - start_pfn; } - free_area_init_node(nodeid, NODE_DATA(nodeid), NULL, zones, + free_area_init_node(nodeid, NODE_DATA(nodeid), zones, start_pfn, NULL); } diff -puN include/linux/mm.h~B-init-no-mem_map include/linux/mm.h --- memhotplug/include/linux/mm.h~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/include/linux/mm.h Thu Aug 5 19:13:41 2004 @@ -601,11 +601,10 @@ static inline pmd_t *pmd_alloc(struct mm } extern void free_area_init(unsigned long * zones_size); -extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, +extern void free_area_init_node(int nid, pg_data_t *pgdat, unsigned long * zones_size, unsigned long zone_start_pfn, unsigned long *zholes_size); -extern void memmap_init_zone(struct page *, unsigned long, int, - unsigned long, unsigned long); +extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long); extern void mem_init(void); extern void show_mem(void); extern void si_meminfo(struct sysinfo * val); diff -puN mm/page_alloc.c~B-init-no-mem_map mm/page_alloc.c --- memhotplug/mm/page_alloc.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/mm/page_alloc.c Thu Aug 5 19:13:41 2004 @@ -1385,9 +1385,10 @@ static void __init calculate_zone_totalp * up by free_all_bootmem() once the early boot process is * done. Non-atomic initialization, single-pass. */ -void __init memmap_init_zone(struct page *start, unsigned long size, int nid, - unsigned long zone, unsigned long start_pfn) +void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone, + unsigned long start_pfn) { + struct page *start = pfn_to_page(start_pfn); struct page *page; for (page = start; page < (start + size); page++) { @@ -1451,8 +1452,8 @@ void zone_init_free_lists(struct pglist_ } #ifndef __HAVE_ARCH_MEMMAP_INIT -#define memmap_init(start, size, nid, zone, start_pfn) \ - memmap_init_zone((start), (size), (nid), (zone), (start_pfn)) +#define memmap_init(size, nid, zone, start_pfn) \ + memmap_init_zone((size), (nid), (zone), (start_pfn)) #endif /* @@ -1467,7 +1468,6 @@ static void __init free_area_init_core(s unsigned long i, j; const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1); int cpu, nid = pgdat->node_id; - struct page *lmem_map = pgdat->node_mem_map; unsigned long zone_start_pfn = pgdat->node_start_pfn; pgdat->nr_zones = 0; @@ -1555,35 +1555,51 @@ static void __init free_area_init_core(s pgdat->nr_zones = j+1; - zone->zone_mem_map = lmem_map; + zone->zone_mem_map = pfn_to_page(zone_start_pfn); zone->zone_start_pfn = zone_start_pfn; if ((zone_start_pfn) & (zone_required_alignment-1)) printk("BUG: wrong zone alignment, it will crash\n"); - memmap_init(lmem_map, size, nid, j, zone_start_pfn); + memmap_init(size, nid, j, zone_start_pfn); zone_start_pfn += size; - lmem_map += size; zone_init_free_lists(pgdat, zone, zone->spanned_pages); } } -void __init free_area_init_node(int nid, struct pglist_data *pgdat, - struct page *node_mem_map, unsigned long *zones_size, - unsigned long node_start_pfn, unsigned long *zholes_size) +static void __init alloc_node_mem_map(struct pglist_data *pgdat) { unsigned long size; + /* + * Make sure that the architecture hasn't already allocated + * a node_mem_map, and that the node contains memory. + */ + if (pgdat->node_mem_map || !pgdat->node_spanned_pages) + return; + + size = (pgdat->node_spanned_pages + 1) * sizeof(struct page); + pgdat->node_mem_map = alloc_bootmem_node(pgdat, size); +#ifndef CONFIG_DISCONTIGMEM + /* + * With no DISCONTIG, the global mem_map is just set as node 0's + */ + if (pgdat == NODE_DATA(0)) + mem_map = NODE_DATA(0)->node_mem_map; +#endif +} + +void __init free_area_init_node(int nid, struct pglist_data *pgdat, + unsigned long *zones_size, unsigned long node_start_pfn, + unsigned long *zholes_size) +{ pgdat->node_id = nid; pgdat->node_start_pfn = node_start_pfn; calculate_zone_totalpages(pgdat, zones_size, zholes_size); - if (!node_mem_map) { - size = (pgdat->node_spanned_pages + 1) * sizeof(struct page); - node_mem_map = alloc_bootmem_node(pgdat, size); - } - pgdat->node_mem_map = node_mem_map; + + alloc_node_mem_map(pgdat); free_area_init_core(pgdat, zones_size, zholes_size); } @@ -1596,9 +1612,8 @@ EXPORT_SYMBOL(contig_page_data); void __init free_area_init(unsigned long *zones_size) { - free_area_init_node(0, &contig_page_data, NULL, zones_size, + free_area_init_node(0, &contig_page_data, zones_size, __pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL); - mem_map = contig_page_data.node_mem_map; } #endif diff -puN arch/v850/kernel/setup.c~B-init-no-mem_map arch/v850/kernel/setup.c --- memhotplug/arch/v850/kernel/setup.c~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/arch/v850/kernel/setup.c Thu Aug 5 19:13:41 2004 @@ -281,7 +281,6 @@ init_mem_alloc (unsigned long ram_start, #error MAX_ORDER is too large for given PAGE_OFFSET (use CONFIG_FORCE_MAX_ZONEORDER to change it) #endif - free_area_init_node (0, NODE_DATA(0), 0, zones_size, + free_area_init_node (0, NODE_DATA(0), zones_size, ADDR_TO_PAGE (PAGE_OFFSET), 0); - mem_map = NODE_DATA(0)->node_mem_map; } diff -puN include/asm-ia64/pgtable.h~B-init-no-mem_map include/asm-ia64/pgtable.h --- memhotplug/include/asm-ia64/pgtable.h~B-init-no-mem_map Thu Aug 5 19:13:41 2004 +++ memhotplug-dave/include/asm-ia64/pgtable.h Thu Aug 5 19:13:41 2004 @@ -520,7 +520,7 @@ do { \ # ifdef CONFIG_VIRTUAL_MEM_MAP /* arch mem_map init routine is needed due to holes in a virtual mem_map */ # define __HAVE_ARCH_MEMMAP_INIT - extern void memmap_init (struct page *start, unsigned long size, int nid, unsigned long zone, + extern void memmap_init (unsigned long size, int nid, unsigned long zone, unsigned long start_pfn); # endif /* CONFIG_VIRTUAL_MEM_MAP */ # endif /* !__ASSEMBLY__ */ _