x86, memblock: Add memblock_x86_to_bootmem()
authorYinghai Lu <yinghai@kernel.org>
Wed, 25 Aug 2010 20:39:15 +0000 (13:39 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 27 Aug 2010 18:08:21 +0000 (11:08 -0700)
memblock_x86_to_bootmem() will reserve memblock.reserved.region in
bootmem after bootmem is set up.

We can use it to with all arches that support memblock later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
arch/x86/include/asm/memblock.h
arch/x86/mm/memblock.c

index c14219a..69cf853 100644 (file)
@@ -4,5 +4,6 @@
 #define ARCH_DISCARD_MEMBLOCK
 
 u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align);
+void memblock_x86_to_bootmem(u64 start, u64 end);
 
 #endif
index 26ba462..8101084 100644 (file)
@@ -85,3 +85,32 @@ u64 __init memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align)
 
        return MEMBLOCK_ERROR;
 }
+
+#ifndef CONFIG_NO_BOOTMEM
+void __init memblock_x86_to_bootmem(u64 start, u64 end)
+{
+       int count;
+       u64 final_start, final_end;
+       struct memblock_region *r;
+
+       /* Take out region array itself */
+       memblock_free_reserved_regions();
+
+       count  = memblock.reserved.cnt;
+       pr_info("(%d early reservations) ==> bootmem [%010llx-%010llx]\n", count, start, end - 1);
+       for_each_memblock(reserved, r) {
+               pr_info("  [%010llx-%010llx] ", (u64)r->base, (u64)r->base + r->size - 1);
+               final_start = max(start, r->base);
+               final_end = min(end, r->base + r->size);
+               if (final_start >= final_end) {
+                       pr_cont("\n");
+                       continue;
+               }
+               pr_cont(" ==> [%010llx-%010llx]\n", final_start, final_end - 1);
+               reserve_bootmem_generic(final_start, final_end - final_start, BOOTMEM_DEFAULT);
+       }
+
+       /* Put region array back ? */
+       memblock_reserve_reserved_regions();
+}
+#endif