don't pass mem_map into init functions
Subsystems (9)
PATCH 1/1 don't pass mem_map into init functions
When using CONFIG_NONLINEAR, a zone's mem_map isn't contiguous, and isn't allocated in the same place. This means that nonlinear doesn't really have a mem_map[] to pass into free_area_init_node() or memmap_init_zone() which makes any sense.
So, this patch removes the 'struct page *mem_map' argument to both of those functions. All non-NUMA architectures just pass a NULL in there, which is ignored. The solution on the NUMA arches is to pass the mem_map in via the pgdat, which works just fine.
To replace the removed arguments, a call to pfn_to_page(node_start_pfn) is made. This is valid because all of the pfn_to_page() implementations rely only on the pgdats, which are already set up at this time. Plus, the pfn_to_page() method should work for any future nonlinear-type code.
Finally, the patch creates a function: node_alloc_mem_map(), which I plan to effectively #ifdef out for nonlinear at some future date.
Compile tested and booted on SMP x86, NUMAQ, and ppc64. Jesse Barnes said he gave it a run on an ia64 box, and needed one additional patch:
http://marc.theaimsgroup.com/?l=linux-kernel&m=109105562606682&q=raw
Jesse, could you follow up to this mail with a copy of your patch?
Attached patch is against 2.6.8-rc2-mm2.
-- Dave
---
memhotplug-dave/arch/alpha/mm/numa.c | 2 - memhotplug-dave/arch/ia64/mm/contig.c | 3 +- memhotplug-dave/arch/ia64/mm/init.c | 2 - memhotplug-dave/arch/ppc64/mm/init.c | 2 - memhotplug-dave/arch/sh/mm/init.c | 2 - memhotplug-dave/include/linux/mm.h | 5 +--- memhotplug-dave/mm/page_alloc.c | 37 ++++++++++++++++++---------------- 7 files changed, 28 insertions(+), 25 deletions(-)
arch/alpha/mm/numa.c renamed from arch/alpha/mm/numa.c~B-init-no-mem_map +1 -1
@@ -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
diff -puN arch/arm26/mm/init.c~B-init-no-mem_map arch/arm26/mm/init.c diff -puN arch/cris/arch-v10/mm/init.c~B-init-no-mem_map arch/cris/arch-v10/mm/init.c diff -puN arch/i386/mm/discontig.c~B-init-no-mem_map arch/i386/mm/discontig.c
arch/ia64/mm/contig.c renamed from arch/ia64/mm/contig.c~B-init-no-mem_map +2 -1
@@ -280,7 +280,8 @@ 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, + contig_page_data.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;
diff -puN arch/ia64/mm/discontig.c~B-init-no-mem_map arch/ia64/mm/discontig.c
arch/ia64/mm/init.c renamed from arch/ia64/mm/init.c~B-init-no-mem_map +1 -1
@@ -437,7 +437,7 @@ memmap_init (struct page *start, unsigne 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 memmap_init_callback_data args;
diff -puN arch/mips/sgi-ip27/ip27-memory.c~B-init-no-mem_map arch/mips/sgi-ip27/ip27-memory.c diff -puN arch/parisc/mm/init.c~B-init-no-mem_map arch/parisc/mm/init.c
arch/ppc64/mm/init.c renamed from arch/ppc64/mm/init.c~B-init-no-mem_map +1 -1
@@ -587,7 +587,7 @@ 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; }
diff -puN arch/ppc64/mm/numa.c~B-init-no-mem_map arch/ppc64/mm/numa.c
arch/sh/mm/init.c renamed from arch/sh/mm/init.c~B-init-no-mem_map +1 -1
@@ -225,7 +225,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 diff -puN arch/sparc/mm/srmmu.c~B-init-no-mem_map arch/sparc/mm/srmmu.c diff -puN arch/sparc/mm/sun4c.c~B-init-no-mem_map arch/sparc/mm/sun4c.c diff -puN arch/sparc64/mm/init.c~B-init-no-mem_map arch/sparc64/mm/init.c diff -puN arch/x86_64/mm/numa.c~B-init-no-mem_map arch/x86_64/mm/numa.c
include/linux/mm.h renamed from include/linux/mm.h~B-init-no-mem_map +2 -3
@@ -590,11 +590,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);
mm/page_alloc.c renamed from mm/page_alloc.c~B-init-no-mem_map +20 -17
@@ -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(sunsigned 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,38 @@ 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) +void __init node_alloc_mem_map (struct pglist_data *pgdat) {unsigned long size; + size = (pgdat->node_spanned_pages +1 ) *sizeof (struct page ); + pgdat->node_mem_map =alloc_bootmem_node (pgdat, size); +} + +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; + +if (!pfn_to_page (node_start_pfn)) +node_alloc_mem_map (pgdat);free_area_init_core (pgdat, zones_size, zholes_size); }
@@ -1596,7 +1599,7 @@ 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; }
_
Quoted 3 lines · Dave Hansen
Jesse, could you follow up to this mail with a copy of your patch?
Attached patch is against 2.6.8-rc2-mm2.
Fix up ia64 specific memory map init function in light of Dave's memmap_init cleanups.
Jesse
arch/ia64/mm/init.c +4 -2
@@ -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);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;
include/asm-ia64/pgtable.h +1 -1
@@ -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__ */
Quoted 11 lines · Dave Hansen
When using
CONFIG_NONLINEAR, a zone'smem_mapisn't contiguous, and
isn't allocated in the same place. This means that nonlinear doesn't really have a mem_map[] to pass intofree_area_init_node()ormemmap_init_zone()which makes any sense.So, this patch removes the 'struct page
*mem_map' argument to both of those functions. All non-NUMA architectures just pass a NULL in there, which is ignored. The solution on the NUMA arches is to pass themem_mapin via the pgdat, which works just fine.
Quoted 8 lines
To replace the removed arguments, a call to
pfn_to_page(node_start_pfn)is made. This is valid because all of thepfn_to_page()implementations rely only on the pgdats, which are already set up at this time. Plus, thepfn_to_page()method should work for any future nonlinear-type code.Finally, the patch creates a function:
node_alloc_mem_map(), which I plan to effectively #ifdef out for nonlinear at some future date.
You wanna take a shot at fixing this up please?
arch/sparc64/mm/init.c: In function `paging_init':arch/sparc64/mm/init.c:1589: warning: passing arg 4 of free_area_init_node' makes integer from pointer without a cast arch/sparc64/mm/init.c:1589: warning: passing arg 5 of free_area_init_node' makes pointer from integer without a cast arch/sparc64/mm/init.c:1589: error: too many arguments to function `free_area_init_node'
Quoted 6 lines · Andrew Morton
You wanna take a shot at fixing this up please?
arch/sparc64/mm/init.c: In function `paging_init':arch/sparc64/mm/init.c:1589: warning: passing arg 4 offree_area_init_node' makes integer from pointer without a cast arch/sparc64/mm/init.c:1589: warning: passing arg 5 offree_area_init_node' makes pointer from integer without a castarch/sparc64/mm/init.c:1589: error: too many arguments to function `free_area_init_node'
Looks like I missed a couple of architectures. This patch, on top of my previous one and Jesse's should clean up the rest.
-- Dave
---
memhotplug-dave/arch/arm/mm/init.c | 2 +- memhotplug-dave/arch/ia64/mm/contig.c | 2 +- memhotplug-dave/arch/mips/sgi-ip27/ip27-memory.c | 2 +- memhotplug-dave/arch/parisc/mm/init.c | 2 +- memhotplug-dave/arch/sparc/mm/srmmu.c | 2 +- memhotplug-dave/arch/sparc/mm/sun4c.c | 2 +- memhotplug-dave/arch/sparc64/mm/init.c | 2 +- memhotplug-dave/arch/x86_64/mm/numa.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-)
arch/arm/mm/init.c renamed from arch/arm/mm/init.c~B2-init-no-mem_map-morearches +1 -1
@@ -502,7 +502,7 @@ 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); }
arch/ia64/mm/contig.c renamed from arch/ia64/mm/contig.c~B2-init-no-mem_map-morearches +1 -1
@@ -267,7 +267,7 @@ 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 {
arch/mips/sgi-ip27/ip27-memory.c renamed from arch/mips/sgi-ip27/ip27-memory.c~B2-init-no-mem_map-morearches +1 -1
@@ -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)
arch/parisc/mm/init.c renamed from arch/parisc/mm/init.c~B2-init-no-mem_map-morearches +1 -1
@@ -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 ); }
arch/sparc/mm/srmmu.c renamed from arch/sparc/mm/srmmu.c~B2-init-no-mem_map-morearches +1 -1
@@ -1341,7 +1341,7 @@ 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; }
arch/sparc/mm/sun4c.c renamed from arch/sparc/mm/sun4c.c~B2-init-no-mem_map-morearches +1 -1
@@ -2114,7 +2114,7 @@ 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; }
arch/sparc64/mm/init.c renamed from arch/sparc64/mm/init.c~B2-init-no-mem_map-morearches +1 -1
@@ -1585,7 +1585,7 @@ 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; }
arch/x86_64/mm/numa.c renamed from arch/x86_64/mm/numa.c~B2-init-no-mem_map-morearches +1 -1
@@ -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 ); }
_
Quoted 5 lines · Dave Hansen
When using
CONFIG_NONLINEAR, a zone'smem_mapisn't contiguous, and isn't allocated in the same place. This means that nonlinear doesn't really have a mem_map[] to pass intofree_area_init_node()ormemmap_init_zone()which makes any sense.
argh, sorry. It's this patch which I dropped due to psychedelic screen syndrome. The "break out zone free list initialization" patch is innocent, and was included in rc3-mm1.
Quoted 10 lines · Andrew Morton
Quoted 5 lines · Dave Hansen
When using
CONFIG_NONLINEAR, a zone'smem_mapisn't contiguous, and isn't allocated in the same place. This means that nonlinear doesn't really have a mem_map[] to pass intofree_area_init_node()ormemmap_init_zone()which makes any sense.argh, sorry. It's this patch which I dropped due to psychedelic screen syndrome. The "break out zone free list initialization" patch is innocent, and was included in rc3-mm1.
OK, here's a replacement for the bad one. I could provide an incremental instead if you prefer.
Turns out I was initializing the mem_map too late. Not only did pfn_to_page() use the pgdats, but it also used mem_map. Not surprisingly, mem_map == NULL did not make things happy.
My earlier testing didn't catch it because I was always using either DISCONTIGMEM or NONLINEAR (even on plain SMP because I'm weird), both of which skip the code that I screwed up.
-- Dave
---
memhotplug-dave/arch/alpha/mm/numa.c | 2 - memhotplug-dave/arch/ia64/mm/contig.c | 3 +- memhotplug-dave/arch/ia64/mm/init.c | 2 - memhotplug-dave/arch/ppc64/mm/init.c | 2 - memhotplug-dave/arch/sh/mm/init.c | 2 - memhotplug-dave/include/linux/mm.h | 5 +--- memhotplug-dave/mm/page_alloc.c | 39 ++++++++++++++++++---------------- 7 files changed, 29 insertions(+), 26 deletions(-)
arch/alpha/mm/numa.c renamed from arch/alpha/mm/numa.c~B-init-no-mem_map +1 -1
@@ -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
diff -puN arch/arm26/mm/init.c~B-init-no-mem_map arch/arm26/mm/init.c diff -puN arch/cris/arch-v10/mm/init.c~B-init-no-mem_map arch/cris/arch-v10/mm/init.c diff -puN arch/i386/mm/discontig.c~B-init-no-mem_map arch/i386/mm/discontig.c
arch/ia64/mm/contig.c renamed from arch/ia64/mm/contig.c~B-init-no-mem_map +2 -1
@@ -280,7 +280,8 @@ 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, + contig_page_data.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;
diff -puN arch/ia64/mm/discontig.c~B-init-no-mem_map arch/ia64/mm/discontig.c
arch/ia64/mm/init.c renamed from arch/ia64/mm/init.c~B-init-no-mem_map +1 -1
@@ -437,7 +437,7 @@ memmap_init (struct page *start, unsigne 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 memmap_init_callback_data args;
diff -puN arch/mips/sgi-ip27/ip27-memory.c~B-init-no-mem_map arch/mips/sgi-ip27/ip27-memory.c diff -puN arch/parisc/mm/init.c~B-init-no-mem_map arch/parisc/mm/init.c
arch/ppc64/mm/init.c renamed from arch/ppc64/mm/init.c~B-init-no-mem_map +1 -1
@@ -587,7 +587,7 @@ 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; }
diff -puN arch/ppc64/mm/numa.c~B-init-no-mem_map arch/ppc64/mm/numa.c
arch/sh/mm/init.c renamed from arch/sh/mm/init.c~B-init-no-mem_map +1 -1
@@ -225,7 +225,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 diff -puN arch/sparc/mm/srmmu.c~B-init-no-mem_map arch/sparc/mm/srmmu.c diff -puN arch/sparc/mm/sun4c.c~B-init-no-mem_map arch/sparc/mm/sun4c.c diff -puN arch/sparc64/mm/init.c~B-init-no-mem_map arch/sparc64/mm/init.c diff -puN arch/x86_64/mm/numa.c~B-init-no-mem_map arch/x86_64/mm/numa.c
include/linux/mm.h renamed from include/linux/mm.h~B-init-no-mem_map +2 -3
@@ -590,11 +590,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);
mm/page_alloc.c renamed from mm/page_alloc.c~B-init-no-mem_map +21 -18
@@ -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(sunsigned 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,39 @@ 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) +void __init node_alloc_mem_map (struct pglist_data *pgdat) {unsigned long size; + size = (pgdat->node_spanned_pages +1 ) *sizeof (struct page ); + pgdat->node_mem_map =alloc_bootmem_node (pgdat, size); + mem_map = contig_page_data.node_mem_map; +} + +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; + +if (!pfn_to_page (node_start_pfn)) +node_alloc_mem_map (pgdat);free_area_init_core (pgdat, zones_size, zholes_size); }
@@ -1596,9 +1600,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
_