Skip to content

Commit

Permalink
ARM: Fix sparsemem with SPARSEMEM_EXTREME enabled
Browse files Browse the repository at this point in the history
When SPARSEMEM_EXTREME is enabled, memory_present() wants to use bootmem
to allocate data structures.  However, we call memory_present() after
declaring memory to bootmem, but before we've reserved areas.

This leads to sparsemem data structures being overwritten later in the
kernel's initialization (when slab initializes.)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Oct 29, 2009
1 parent c06e004 commit 657e12f
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion arch/arm/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
struct membank *bank = &mi->bank[i];
if (!bank->highmem)
free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
}

/*
Expand Down Expand Up @@ -370,6 +369,19 @@ int pfn_valid(unsigned long pfn)
return 0;
}
EXPORT_SYMBOL(pfn_valid);

static void arm_memory_present(struct meminfo *mi, int node)
{
}
#else
static void arm_memory_present(struct meminfo *mi, int node)
{
int i;
for_each_nodebank(i, mi, node) {
struct membank *bank = &mi->bank[i];
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
}
}
#endif

static int __init meminfo_cmp(const void *_a, const void *_b)
Expand Down Expand Up @@ -427,6 +439,12 @@ void __init bootmem_init(void)
*/
if (node == initrd_node)
bootmem_reserve_initrd(node);

/*
* Sparsemem tries to allocate bootmem in memory_present(),
* so must be done after the fixed reservations
*/
arm_memory_present(mi, node);
}

/*
Expand Down

0 comments on commit 657e12f

Please sign in to comment.