powerpc: Fix bootmem reservation on uninitialized node
careful_allocation() was calling into the bootmem allocator for nodes which had not been fully initialized and caused a previous bug: http://patchwork.ozlabs.org/patch/10528/ So, I merged a few broken out loops in do_init_bootmem() to fix it. That changed the code ordering. I think this bug is triggered by having reserved areas for a node which are spanned by another node's contents. In the mark_reserved_regions_for_nid() code, we attempt to reserve the area for a node before we have allocated the NODE_DATA() for that nid. We do this since I reordered that loop. I suck. This is causing crashes at bootup on some systems, as reported by Jon Tollefson. This may only present on some systems that have 16GB pages reserved. But, it can probably happen on any system that is trying to reserve large swaths of memory that happen to span other nodes' contents. This commit ensures that we do not touch bootmem for any node which has not been initialized, and also removes a compile warning about an unused variable. Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
48f797de55
Коммит
a4c74ddd5e
|
@ -901,10 +901,17 @@ static void mark_reserved_regions_for_nid(int nid)
|
||||||
if (end_pfn > node_ar.end_pfn)
|
if (end_pfn > node_ar.end_pfn)
|
||||||
reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
|
reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
|
||||||
- (start_pfn << PAGE_SHIFT);
|
- (start_pfn << PAGE_SHIFT);
|
||||||
dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
|
/*
|
||||||
reserve_size, node_ar.nid);
|
* Only worry about *this* node, others may not
|
||||||
reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
|
* yet have valid NODE_DATA().
|
||||||
reserve_size, BOOTMEM_DEFAULT);
|
*/
|
||||||
|
if (node_ar.nid == nid) {
|
||||||
|
dbg("reserve_bootmem %lx %lx nid=%d\n",
|
||||||
|
physbase, reserve_size, node_ar.nid);
|
||||||
|
reserve_bootmem_node(NODE_DATA(node_ar.nid),
|
||||||
|
physbase, reserve_size,
|
||||||
|
BOOTMEM_DEFAULT);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* if reserved region is contained in the active region
|
* if reserved region is contained in the active region
|
||||||
* then done.
|
* then done.
|
||||||
|
@ -929,7 +936,6 @@ static void mark_reserved_regions_for_nid(int nid)
|
||||||
void __init do_init_bootmem(void)
|
void __init do_init_bootmem(void)
|
||||||
{
|
{
|
||||||
int nid;
|
int nid;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
min_low_pfn = 0;
|
min_low_pfn = 0;
|
||||||
max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
|
max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче