mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-18 10:13:57 +08:00
[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>
This commit is contained in:
parent
1e185b97b4
commit
fb6d73d301
@ -200,6 +200,8 @@ void show_mem(void)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
pgdat_resize_lock(pgdat, &flags);
|
pgdat_resize_lock(pgdat, &flags);
|
||||||
for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
||||||
|
if (!pfn_valid(pgdat->node_start_pfn + i))
|
||||||
|
continue;
|
||||||
page = pgdat_page_nr(pgdat, i);
|
page = pgdat_page_nr(pgdat, i);
|
||||||
total++;
|
total++;
|
||||||
if (PageHighMem(page))
|
if (PageHighMem(page))
|
||||||
@ -336,7 +338,7 @@ void __init mem_init(void)
|
|||||||
struct page *page;
|
struct page *page;
|
||||||
unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
|
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);
|
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
|
||||||
|
|
||||||
#ifdef CONFIG_NEED_MULTIPLE_NODES
|
#ifdef CONFIG_NEED_MULTIPLE_NODES
|
||||||
@ -348,11 +350,13 @@ void __init mem_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
max_mapnr = num_physpages;
|
max_mapnr = max_pfn;
|
||||||
totalram_pages += free_all_bootmem();
|
totalram_pages += free_all_bootmem();
|
||||||
#endif
|
#endif
|
||||||
for_each_pgdat(pgdat) {
|
for_each_pgdat(pgdat) {
|
||||||
for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
||||||
|
if (!pfn_valid(pgdat->node_start_pfn + i))
|
||||||
|
continue;
|
||||||
page = pgdat_page_nr(pgdat, i);
|
page = pgdat_page_nr(pgdat, i);
|
||||||
if (PageReserved(page))
|
if (PageReserved(page))
|
||||||
reservedpages++;
|
reservedpages++;
|
||||||
|
@ -483,6 +483,7 @@ static void __init setup_nonnuma(void)
|
|||||||
{
|
{
|
||||||
unsigned long top_of_ram = lmb_end_of_DRAM();
|
unsigned long top_of_ram = lmb_end_of_DRAM();
|
||||||
unsigned long total_ram = lmb_phys_mem_size();
|
unsigned long total_ram = lmb_phys_mem_size();
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
|
printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
|
||||||
top_of_ram, total_ram);
|
top_of_ram, total_ram);
|
||||||
@ -490,7 +491,9 @@ static void __init setup_nonnuma(void)
|
|||||||
(top_of_ram - total_ram) >> 20);
|
(top_of_ram - total_ram) >> 20);
|
||||||
|
|
||||||
map_cpu_to_node(boot_cpuid, 0);
|
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);
|
node_set_online(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user