Skip to content

Commit

Permalink
[PATCH] powerpc: Fix sparsemem with memory holes [was Re: ppc64 oops..]
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mackerras authored and Linus Torvalds committed Nov 16, 2005
1 parent 1e185b9 commit fb6d73d
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
8 changes: 6 additions & 2 deletions arch/powerpc/mm/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ void show_mem(void)
unsigned long flags;
pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; i++) {
if (!pfn_valid(pgdat->node_start_pfn + i))
continue;
page = pgdat_page_nr(pgdat, i);
total++;
if (PageHighMem(page))
Expand Down Expand Up @@ -336,7 +338,7 @@ void __init mem_init(void)
struct page *page;
unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;

num_physpages = max_pfn; /* RAM is assumed contiguous */
num_physpages = lmb.memory.size >> PAGE_SHIFT;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);

#ifdef CONFIG_NEED_MULTIPLE_NODES
Expand All @@ -348,11 +350,13 @@ void __init mem_init(void)
}
}
#else
max_mapnr = num_physpages;
max_mapnr = max_pfn;
totalram_pages += free_all_bootmem();
#endif
for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_spanned_pages; i++) {
if (!pfn_valid(pgdat->node_start_pfn + i))
continue;
page = pgdat_page_nr(pgdat, i);
if (PageReserved(page))
reservedpages++;
Expand Down
5 changes: 4 additions & 1 deletion arch/powerpc/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,14 +483,17 @@ static void __init setup_nonnuma(void)
{
unsigned long top_of_ram = lmb_end_of_DRAM();
unsigned long total_ram = lmb_phys_mem_size();
unsigned int i;

printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
top_of_ram, total_ram);
printk(KERN_INFO "Memory hole size: %ldMB\n",
(top_of_ram - total_ram) >> 20);

map_cpu_to_node(boot_cpuid, 0);
add_region(0, 0, lmb_end_of_DRAM() >> PAGE_SHIFT);
for (i = 0; i < lmb.memory.cnt; ++i)
add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
lmb_size_pages(&lmb.memory, i));
node_set_online(0);
}

Expand Down

0 comments on commit fb6d73d

Please sign in to comment.