Subject: [PATCH] memblock: Add checking about illegal using memblock After memblock is not used anymore, Clear the memblock so we will not use it wrongly. Signed-off-by: Yinghai Lu --- arch/x86/mm/init_32.c | 3 +++ arch/x86/mm/init_64.c | 2 ++ include/linux/memblock.h | 1 + mm/memblock.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+) Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -759,6 +759,9 @@ void __init mem_init(void) if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp))) reservedpages++; + /* clear to catch wrong usage */ + memblock_clear(); + codesize = (unsigned long) &_etext - (unsigned long) &_text; datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; Index: linux-2.6/arch/x86/mm/init_64.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_64.c +++ linux-2.6/arch/x86/mm/init_64.c @@ -701,6 +701,8 @@ void __init mem_init(void) #endif reservedpages = max_pfn - totalram_pages - absent_pages; + /* clear to catch wrong usage */ + memblock_clear(); after_bootmem = 1; codesize = (unsigned long) &_etext - (unsigned long) &_text; Index: linux-2.6/include/linux/memblock.h =================================================================== --- linux-2.6.orig/include/linux/memblock.h +++ linux-2.6/include/linux/memblock.h @@ -46,6 +46,7 @@ extern int memblock_debug; #define memblock_dbg(fmt, ...) \ if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +void memblock_clear(void); phys_addr_t memblock_find_in_range_node(phys_addr_t start, phys_addr_t end, phys_addr_t size, phys_addr_t align, int nid); phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, Index: linux-2.6/mm/memblock.c =================================================================== --- linux-2.6.orig/mm/memblock.c +++ linux-2.6/mm/memblock.c @@ -101,6 +101,8 @@ phys_addr_t __init_memblock memblock_fin phys_addr_t this_start, this_end, cand; u64 i; + WARN_ONCE(!memblock.reserved.max, "memblock.reserved was cleared already!"); + /* pump up @end */ if (end == MEMBLOCK_ALLOC_ACCESSIBLE) end = memblock.current_limit; @@ -143,6 +145,15 @@ phys_addr_t __init_memblock memblock_fin MAX_NUMNODES); } +/* + * Clear memblock + */ +void __init_memblock memblock_clear(void) +{ + memset(&memblock.reserved, 0, sizeof(memblock.reserved)); + memset(&memblock.memory, 0, sizeof(memblock.memory)); +} + static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r) { type->total_size -= type->regions[r].size; @@ -448,11 +459,15 @@ repeat: int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size, int nid) { + WARN_ONCE(!memblock.memory.max, "memblock.memory was cleared already!"); + return memblock_add_region(&memblock.memory, base, size, nid); } int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) { + WARN_ONCE(!memblock.memory.max, "memblock.memory was cleared already!"); + return memblock_add_region(&memblock.memory, base, size, MAX_NUMNODES); } @@ -547,11 +562,15 @@ static int __init_memblock __memblock_re int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size) { + WARN_ONCE(!memblock.memory.max, "memblock.memory was cleared already!"); + return __memblock_remove(&memblock.memory, base, size); } int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size) { + WARN_ONCE(!memblock.reserved.max, "memblock.reserved was cleared already!"); + memblock_dbg(" memblock_free: [%#016llx-%#016llx] %pF\n", (unsigned long long)base, (unsigned long long)base + size, @@ -564,6 +583,7 @@ int __init_memblock memblock_reserve(phy { struct memblock_type *_rgn = &memblock.reserved; + WARN_ONCE(!memblock.reserved.max, "memblock.reserved was cleared already!"); memblock_dbg("memblock_reserve: [%#016llx-%#016llx] %pF\n", (unsigned long long)base, (unsigned long long)base + size, @@ -604,6 +624,9 @@ void __init_memblock __next_free_mem_ran int mi = *idx & 0xffffffff; int ri = *idx >> 32; + WARN_ONCE(!mem->max, "memblock.memory was cleared already!"); + WARN_ONCE(!rsv->max, "memblock.reserved was cleared already!"); + for ( ; mi < mem->cnt; mi++) { struct memblock_region *m = &mem->regions[mi]; phys_addr_t m_start = m->base; @@ -667,6 +690,9 @@ void __init_memblock __next_free_mem_ran int mi = *idx & 0xffffffff; int ri = *idx >> 32; + WARN_ONCE(!mem->max, "memblock.memory was cleared already!"); + WARN_ONCE(!rsv->max, "memblock.reserved was cleared already!"); + if (*idx == (u64)ULLONG_MAX) { mi = mem->cnt - 1; ri = rsv->cnt; @@ -763,6 +789,8 @@ int __init_memblock memblock_set_node(ph int start_rgn, end_rgn; int i, ret; + WARN_ONCE(!memblock.memory.max, "memblock.memory was cleared already!"); + ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn); if (ret) return ret;