diff options
Diffstat (limited to 'arch/arm/mm/init.c')
-rw-r--r-- | arch/arm/mm/init.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 9b7f0bf26f57..82c4b4217989 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -79,7 +79,7 @@ void show_mem(void) | |||
79 | show_free_areas(); | 79 | show_free_areas(); |
80 | for_each_online_node(node) { | 80 | for_each_online_node(node) { |
81 | pg_data_t *n = NODE_DATA(node); | 81 | pg_data_t *n = NODE_DATA(node); |
82 | struct page *map = n->node_mem_map - n->node_start_pfn; | 82 | struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn; |
83 | 83 | ||
84 | for_each_nodebank (i,mi,node) { | 84 | for_each_nodebank (i,mi,node) { |
85 | struct membank *bank = &mi->bank[i]; | 85 | struct membank *bank = &mi->bank[i]; |
@@ -207,10 +207,8 @@ static inline void map_memory_bank(struct membank *bank) | |||
207 | #endif | 207 | #endif |
208 | } | 208 | } |
209 | 209 | ||
210 | static unsigned long __init | 210 | static unsigned long __init bootmem_init_node(int node, struct meminfo *mi) |
211 | bootmem_init_node(int node, int initrd_node, struct meminfo *mi) | ||
212 | { | 211 | { |
213 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; | ||
214 | unsigned long start_pfn, end_pfn, boot_pfn; | 212 | unsigned long start_pfn, end_pfn, boot_pfn; |
215 | unsigned int boot_pages; | 213 | unsigned int boot_pages; |
216 | pg_data_t *pgdat; | 214 | pg_data_t *pgdat; |
@@ -260,6 +258,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) | |||
260 | for_each_nodebank(i, mi, node) { | 258 | for_each_nodebank(i, mi, node) { |
261 | struct membank *bank = &mi->bank[i]; | 259 | struct membank *bank = &mi->bank[i]; |
262 | free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); | 260 | free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); |
261 | memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); | ||
263 | } | 262 | } |
264 | 263 | ||
265 | /* | 264 | /* |
@@ -268,31 +267,39 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) | |||
268 | reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, | 267 | reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, |
269 | boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); | 268 | boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); |
270 | 269 | ||
271 | /* | 270 | return end_pfn; |
272 | * Reserve any special node zero regions. | 271 | } |
273 | */ | ||
274 | if (node == 0) | ||
275 | reserve_node_zero(pgdat); | ||
276 | 272 | ||
273 | static void __init bootmem_reserve_initrd(int node) | ||
274 | { | ||
277 | #ifdef CONFIG_BLK_DEV_INITRD | 275 | #ifdef CONFIG_BLK_DEV_INITRD |
278 | /* | 276 | pg_data_t *pgdat = NODE_DATA(node); |
279 | * If the initrd is in this node, reserve its memory. | 277 | int res; |
280 | */ | 278 | |
281 | if (node == initrd_node) { | 279 | res = reserve_bootmem_node(pgdat, phys_initrd_start, |
282 | int res = reserve_bootmem_node(pgdat, phys_initrd_start, | 280 | phys_initrd_size, BOOTMEM_EXCLUSIVE); |
283 | phys_initrd_size, BOOTMEM_EXCLUSIVE); | 281 | |
284 | 282 | if (res == 0) { | |
285 | if (res == 0) { | 283 | initrd_start = __phys_to_virt(phys_initrd_start); |
286 | initrd_start = __phys_to_virt(phys_initrd_start); | 284 | initrd_end = initrd_start + phys_initrd_size; |
287 | initrd_end = initrd_start + phys_initrd_size; | 285 | } else { |
288 | } else { | 286 | printk(KERN_ERR |
289 | printk(KERN_ERR | 287 | "INITRD: 0x%08lx+0x%08lx overlaps in-use " |
290 | "INITRD: 0x%08lx+0x%08lx overlaps in-use " | 288 | "memory region - disabling initrd\n", |
291 | "memory region - disabling initrd\n", | 289 | phys_initrd_start, phys_initrd_size); |
292 | phys_initrd_start, phys_initrd_size); | ||
293 | } | ||
294 | } | 290 | } |
295 | #endif | 291 | #endif |
292 | } | ||
293 | |||
294 | static void __init bootmem_free_node(int node, struct meminfo *mi) | ||
295 | { | ||
296 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; | ||
297 | unsigned long start_pfn, end_pfn; | ||
298 | pg_data_t *pgdat = NODE_DATA(node); | ||
299 | int i; | ||
300 | |||
301 | start_pfn = pgdat->bdata->node_min_pfn; | ||
302 | end_pfn = pgdat->bdata->node_low_pfn; | ||
296 | 303 | ||
297 | /* | 304 | /* |
298 | * initialise the zones within this node. | 305 | * initialise the zones within this node. |
@@ -322,8 +329,6 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) | |||
322 | arch_adjust_zones(node, zone_size, zhole_size); | 329 | arch_adjust_zones(node, zone_size, zhole_size); |
323 | 330 | ||
324 | free_area_init_node(node, zone_size, start_pfn, zhole_size); | 331 | free_area_init_node(node, zone_size, start_pfn, zhole_size); |
325 | |||
326 | return end_pfn; | ||
327 | } | 332 | } |
328 | 333 | ||
329 | void __init bootmem_init(struct meminfo *mi) | 334 | void __init bootmem_init(struct meminfo *mi) |
@@ -342,9 +347,19 @@ void __init bootmem_init(struct meminfo *mi) | |||
342 | * Run through each node initialising the bootmem allocator. | 347 | * Run through each node initialising the bootmem allocator. |
343 | */ | 348 | */ |
344 | for_each_node(node) { | 349 | for_each_node(node) { |
345 | unsigned long end_pfn; | 350 | unsigned long end_pfn = bootmem_init_node(node, mi); |
346 | 351 | ||
347 | end_pfn = bootmem_init_node(node, initrd_node, mi); | 352 | /* |
353 | * Reserve any special node zero regions. | ||
354 | */ | ||
355 | if (node == 0) | ||
356 | reserve_node_zero(NODE_DATA(node)); | ||
357 | |||
358 | /* | ||
359 | * If the initrd is in this node, reserve its memory. | ||
360 | */ | ||
361 | if (node == initrd_node) | ||
362 | bootmem_reserve_initrd(node); | ||
348 | 363 | ||
349 | /* | 364 | /* |
350 | * Remember the highest memory PFN. | 365 | * Remember the highest memory PFN. |
@@ -353,6 +368,19 @@ void __init bootmem_init(struct meminfo *mi) | |||
353 | memend_pfn = end_pfn; | 368 | memend_pfn = end_pfn; |
354 | } | 369 | } |
355 | 370 | ||
371 | /* | ||
372 | * sparse_init() needs the bootmem allocator up and running. | ||
373 | */ | ||
374 | sparse_init(); | ||
375 | |||
376 | /* | ||
377 | * Now free memory in each node - free_area_init_node needs | ||
378 | * the sparse mem_map arrays initialized by sparse_init() | ||
379 | * for memmap_init_zone(), otherwise all PFNs are invalid. | ||
380 | */ | ||
381 | for_each_node(node) | ||
382 | bootmem_free_node(node, mi); | ||
383 | |||
356 | high_memory = __va(memend_pfn << PAGE_SHIFT); | 384 | high_memory = __va(memend_pfn << PAGE_SHIFT); |
357 | 385 | ||
358 | /* | 386 | /* |