aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMel Gorman <mel@csn.ul.ie>2006-10-11 04:20:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-11 14:14:14 -0400
commit6391af174ad75f72e92043c1dd8302660a2fec58 (patch)
tree43dfb9a1acfbdabb820180834d4e8efdcfcbe46e
parent4e0fadfcf62e252d2b14de0e0927eb2830c0c28c (diff)
[PATCH] mm: use symbolic names instead of indices for zone initialisation
Arch-independent zone-sizing is using indices instead of symbolic names to offset within an array related to zones (max_zone_pfns). The unintended impact is that ZONE_DMA and ZONE_NORMAL is initialised on powerpc instead of ZONE_DMA and ZONE_HIGHMEM when CONFIG_HIGHMEM is set. As a result, the the machine fails to boot but will boot with CONFIG_HIGHMEM turned off. The following patch properly initialises the max_zone_pfns[] array and uses symbolic names instead of indices in each architecture using arch-independent zone-sizing. Two users have successfully booted their powerpcs with it (one an ibook G4). It has also been boot tested on x86, x86_64, ppc64 and ia64. Please merge for 2.6.19-rc2. Credit to Benjamin Herrenschmidt for identifying the bug and rolling the first fix. Additional credit to Johannes Berg and Andreas Schwab for reporting the problem and testing on powerpc. Signed-off-by: Mel Gorman <mel@csn.ul.ie> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/setup.c13
-rw-r--r--arch/i386/mm/discontig.c11
-rw-r--r--arch/ia64/mm/contig.c1
-rw-r--r--arch/ia64/mm/discontig.c1
-rw-r--r--arch/powerpc/mm/mem.c7
-rw-r--r--arch/powerpc/mm/numa.c6
-rw-r--r--arch/ppc/mm/init.c7
-rw-r--r--arch/x86_64/mm/init.c9
-rw-r--r--arch/x86_64/mm/numa.c8
9 files changed, 36 insertions, 27 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 000cf03751fe..519e63c3c130 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1083,16 +1083,15 @@ static unsigned long __init setup_memory(void)
1083 1083
1084void __init zone_sizes_init(void) 1084void __init zone_sizes_init(void)
1085{ 1085{
1086 unsigned long max_zone_pfns[MAX_NR_ZONES];
1087 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
1088 max_zone_pfns[ZONE_DMA] =
1089 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
1090 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
1086#ifdef CONFIG_HIGHMEM 1091#ifdef CONFIG_HIGHMEM
1087 unsigned long max_zone_pfns[MAX_NR_ZONES] = { 1092 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
1088 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1089 max_low_pfn,
1090 highend_pfn};
1091 add_active_range(0, 0, highend_pfn); 1093 add_active_range(0, 0, highend_pfn);
1092#else 1094#else
1093 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
1094 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1095 max_low_pfn};
1096 add_active_range(0, 0, max_low_pfn); 1095 add_active_range(0, 0, max_low_pfn);
1097#endif 1096#endif
1098 1097
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 455597db84df..ddbdb0336f28 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -356,11 +356,12 @@ void __init numa_kva_reserve(void)
356void __init zone_sizes_init(void) 356void __init zone_sizes_init(void)
357{ 357{
358 int nid; 358 int nid;
359 unsigned long max_zone_pfns[MAX_NR_ZONES] = { 359 unsigned long max_zone_pfns[MAX_NR_ZONES];
360 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, 360 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
361 max_low_pfn, 361 max_zone_pfns[ZONE_DMA] =
362 highend_pfn 362 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
363 }; 363 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
364 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
364 365
365 /* If SRAT has not registered memory, register it now */ 366 /* If SRAT has not registered memory, register it now */
366 if (find_max_pfn_with_active_regions() == 0) { 367 if (find_max_pfn_with_active_regions() == 0) {
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index daf977ff2920..82deaa3a7c48 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -233,6 +233,7 @@ paging_init (void)
233 efi_memmap_walk(count_pages, &num_physpages); 233 efi_memmap_walk(count_pages, &num_physpages);
234 234
235 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; 235 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
236 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
236 max_zone_pfns[ZONE_DMA] = max_dma; 237 max_zone_pfns[ZONE_DMA] = max_dma;
237 max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 238 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
238 239
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index d497b6b0f5b2..96722cb1b49d 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -709,6 +709,7 @@ void __init paging_init(void)
709 max_pfn = mem_data[node].max_pfn; 709 max_pfn = mem_data[node].max_pfn;
710 } 710 }
711 711
712 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
712 max_zone_pfns[ZONE_DMA] = max_dma; 713 max_zone_pfns[ZONE_DMA] = max_dma;
713 max_zone_pfns[ZONE_NORMAL] = max_pfn; 714 max_zone_pfns[ZONE_NORMAL] = max_pfn;
714 free_area_init_nodes(max_zone_pfns); 715 free_area_init_nodes(max_zone_pfns);
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 16fe027bbc12..d1c0758c5611 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -307,11 +307,12 @@ void __init paging_init(void)
307 top_of_ram, total_ram); 307 top_of_ram, total_ram);
308 printk(KERN_DEBUG "Memory hole size: %ldMB\n", 308 printk(KERN_DEBUG "Memory hole size: %ldMB\n",
309 (top_of_ram - total_ram) >> 20); 309 (top_of_ram - total_ram) >> 20);
310 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
310#ifdef CONFIG_HIGHMEM 311#ifdef CONFIG_HIGHMEM
311 max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; 312 max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
312 max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT; 313 max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT;
313#else 314#else
314 max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT; 315 max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
315#endif 316#endif
316 free_area_init_nodes(max_zone_pfns); 317 free_area_init_nodes(max_zone_pfns);
317} 318}
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 43c272075e1a..9da01dc8cfd9 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -617,9 +617,9 @@ void __init do_init_bootmem(void)
617 617
618void __init paging_init(void) 618void __init paging_init(void)
619{ 619{
620 unsigned long max_zone_pfns[MAX_NR_ZONES] = { 620 unsigned long max_zone_pfns[MAX_NR_ZONES];
621 lmb_end_of_DRAM() >> PAGE_SHIFT 621 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
622 }; 622 max_zone_pfns[ZONE_DMA] = lmb_end_of_DRAM() >> PAGE_SHIFT;
623 free_area_init_nodes(max_zone_pfns); 623 free_area_init_nodes(max_zone_pfns);
624} 624}
625 625
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 410200046af1..c374e53ae03a 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -374,11 +374,12 @@ void __init paging_init(void)
374 end_pfn = start_pfn + (total_memory >> PAGE_SHIFT); 374 end_pfn = start_pfn + (total_memory >> PAGE_SHIFT);
375 add_active_range(0, start_pfn, end_pfn); 375 add_active_range(0, start_pfn, end_pfn);
376 376
377 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
377#ifdef CONFIG_HIGHMEM 378#ifdef CONFIG_HIGHMEM
378 max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; 379 max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
379 max_zone_pfns[1] = total_memory >> PAGE_SHIFT; 380 max_zone_pfns[ZONE_HIGHMEM] = total_memory >> PAGE_SHIFT;
380#else 381#else
381 max_zone_pfns[0] = total_memory >> PAGE_SHIFT; 382 max_zone_pfns[ZONE_DMA] = total_memory >> PAGE_SHIFT;
382#endif /* CONFIG_HIGHMEM */ 383#endif /* CONFIG_HIGHMEM */
383 free_area_init_nodes(max_zone_pfns); 384 free_area_init_nodes(max_zone_pfns);
384} 385}
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 19c72520a868..971dc1181e69 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -406,9 +406,12 @@ void __cpuinit zap_low_mappings(int cpu)
406#ifndef CONFIG_NUMA 406#ifndef CONFIG_NUMA
407void __init paging_init(void) 407void __init paging_init(void)
408{ 408{
409 unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN, 409 unsigned long max_zone_pfns[MAX_NR_ZONES];
410 MAX_DMA32_PFN, 410 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
411 end_pfn}; 411 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
412 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
413 max_zone_pfns[ZONE_NORMAL] = end_pfn;
414
412 memory_present(0, 0, end_pfn); 415 memory_present(0, 0, end_pfn);
413 sparse_init(); 416 sparse_init();
414 free_area_init_nodes(max_zone_pfns); 417 free_area_init_nodes(max_zone_pfns);
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 829a008bd39b..2ee2e003606c 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -338,9 +338,11 @@ static void __init arch_sparse_init(void)
338void __init paging_init(void) 338void __init paging_init(void)
339{ 339{
340 int i; 340 int i;
341 unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN, 341 unsigned long max_zone_pfns[MAX_NR_ZONES];
342 MAX_DMA32_PFN, 342 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
343 end_pfn}; 343 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
344 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
345 max_zone_pfns[ZONE_NORMAL] = end_pfn;
344 346
345 arch_sparse_init(); 347 arch_sparse_init();
346 348