aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-15 19:43:26 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-15 19:57:12 -0500
commitfb6d73d3014babb69f5cc2d1d78b31e9d09fc5df (patch)
tree9d8ee68b8754fc57948098945113871aee0b23bb
parent1e185b97b4364063f1135604b87f8d8469944233 (diff)
[PATCH] powerpc: Fix sparsemem with memory holes [was Re: ppc64 oops..]
This patch should fix the crashes we have been seeing on 64-bit powerpc systems with a memory hole when sparsemem is enabled. I'd appreciate it if people who know more about NUMA and sparsemem than me could look over it. There were two bugs. The first was that if NUMA was enabled but there was no NUMA information for the machine, the setup_nonnuma() function was adding a single region, assuming memory was contiguous. The second was that the loops in mem_init() and show_mem() assumed that all pages within the span of a pgdat were valid (had a valid struct page). I also fixed the incorrect setting of num_physpages that Mike Kravetz pointed out. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/powerpc/mm/mem.c8
-rw-r--r--arch/powerpc/mm/numa.c5
2 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index e2c95fcb8055..4bd7b0a70996 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -200,6 +200,8 @@ void show_mem(void)
200 unsigned long flags; 200 unsigned long flags;
201 pgdat_resize_lock(pgdat, &flags); 201 pgdat_resize_lock(pgdat, &flags);
202 for (i = 0; i < pgdat->node_spanned_pages; i++) { 202 for (i = 0; i < pgdat->node_spanned_pages; i++) {
203 if (!pfn_valid(pgdat->node_start_pfn + i))
204 continue;
203 page = pgdat_page_nr(pgdat, i); 205 page = pgdat_page_nr(pgdat, i);
204 total++; 206 total++;
205 if (PageHighMem(page)) 207 if (PageHighMem(page))
@@ -336,7 +338,7 @@ void __init mem_init(void)
336 struct page *page; 338 struct page *page;
337 unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; 339 unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
338 340
339 num_physpages = max_pfn; /* RAM is assumed contiguous */ 341 num_physpages = lmb.memory.size >> PAGE_SHIFT;
340 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); 342 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
341 343
342#ifdef CONFIG_NEED_MULTIPLE_NODES 344#ifdef CONFIG_NEED_MULTIPLE_NODES
@@ -348,11 +350,13 @@ void __init mem_init(void)
348 } 350 }
349 } 351 }
350#else 352#else
351 max_mapnr = num_physpages; 353 max_mapnr = max_pfn;
352 totalram_pages += free_all_bootmem(); 354 totalram_pages += free_all_bootmem();
353#endif 355#endif
354 for_each_pgdat(pgdat) { 356 for_each_pgdat(pgdat) {
355 for (i = 0; i < pgdat->node_spanned_pages; i++) { 357 for (i = 0; i < pgdat->node_spanned_pages; i++) {
358 if (!pfn_valid(pgdat->node_start_pfn + i))
359 continue;
356 page = pgdat_page_nr(pgdat, i); 360 page = pgdat_page_nr(pgdat, i);
357 if (PageReserved(page)) 361 if (PageReserved(page))
358 reservedpages++; 362 reservedpages++;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bd2cf1336885..f72cf87364cb 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -483,6 +483,7 @@ static void __init setup_nonnuma(void)
483{ 483{
484 unsigned long top_of_ram = lmb_end_of_DRAM(); 484 unsigned long top_of_ram = lmb_end_of_DRAM();
485 unsigned long total_ram = lmb_phys_mem_size(); 485 unsigned long total_ram = lmb_phys_mem_size();
486 unsigned int i;
486 487
487 printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 488 printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
488 top_of_ram, total_ram); 489 top_of_ram, total_ram);
@@ -490,7 +491,9 @@ static void __init setup_nonnuma(void)
490 (top_of_ram - total_ram) >> 20); 491 (top_of_ram - total_ram) >> 20);
491 492
492 map_cpu_to_node(boot_cpuid, 0); 493 map_cpu_to_node(boot_cpuid, 0);
493 add_region(0, 0, lmb_end_of_DRAM() >> PAGE_SHIFT); 494 for (i = 0; i < lmb.memory.cnt; ++i)
495 add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
496 lmb_size_pages(&lmb.memory, i));
494 node_set_online(0); 497 node_set_online(0);
495} 498}
496 499