On Mon, Oct 11, 2010 at 8:25 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
If memblock_remove is used on the end of memory with this patch,
mem_init accesses off the end of the array of page structures because
of the discrepancy between memblock.memory and membank on the number
of the last pfn. memblock.memory is used to determine the memory
zones in arm_bootmem_free, which eventually is used to create the
array of page structures, but mem_init iterates over membank and calls
pfn_to_page on pfns up to bank_pfn_end.
Converting show_mem and mem_init to use memblock.memory fixes it:
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 52192f4..6c2b8a0 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -81,18 +81,16 @@ void show_mem(void)
{
int free = 0, total = 0, reserved = 0;
int shared = 0, cached = 0, slab = 0, i;
- struct meminfo * mi = &meminfo;
printk("Mem-info:\n");
show_free_areas();
- for_each_bank (i, mi) {
- struct membank *bank = &mi->bank[i];
+ for (i = 0; i < memblock.memory.cnt; i++) {
unsigned int pfn1, pfn2;
struct page *page, *end;
- pfn1 = bank_pfn_start(bank);
- pfn2 = bank_pfn_end(bank);
+ pfn1 = memblock_start_pfn(&memblock.memory, i);
+ pfn2 = memblock_end_pfn(&memblock.memory, i);
page = pfn_to_page(pfn1);
end = pfn_to_page(pfn2 - 1) + 1;
@@ -520,13 +518,12 @@ void __init mem_init(void)
reserved_pages = free_pages = 0;
- for_each_bank(i, &meminfo) {
- struct membank *bank = &meminfo.bank[i];
+ for (i = 0; i < memblock.memory.cnt; i++) {
unsigned int pfn1, pfn2;
struct page *page, *end;
- pfn1 = bank_pfn_start(bank);
- pfn2 = bank_pfn_end(bank);
+ pfn1 = memblock_start_pfn(&memblock.memory, i);
+ pfn2 = memblock_end_pfn(&memblock.memory, i);
page = pfn_to_page(pfn1);
end = pfn_to_page(pfn2 - 1) + 1;
--