aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-08-25 16:39:17 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-08-27 14:12:29 -0400
commit72d7c3b33c980843e756681fb4867dc1efd62a76 (patch)
tree9607345d9fa055dd501aacf0772258fb72897035
parent301ff3e88ef9ff4bdb92f36a3e6170fce4c9dd34 (diff)
x86: Use memblock to replace early_res
1. replace find_e820_area with memblock_find_in_range 2. replace reserve_early with memblock_x86_reserve_range 3. replace free_early with memblock_x86_free_range. 4. NO_BOOTMEM will switch to use memblock too. 5. use _e820, _early wrap in the patch, in following patch, will replace them all 6. because memblock_x86_free_range support partial free, we can remove some special care 7. Need to make sure that memblock_find_in_range() is called after memblock_x86_fill() so adjust some calling later in setup.c::setup_arch() -- corruption_check and mptable_update -v2: Move reserve_brk() early Before fill_memblock_area, to avoid overlap between brk and memblock_find_in_range() that could happen We have more then 128 RAM entry in E820 tables, and memblock_x86_fill() could use memblock_find_in_range() to find a new place for memblock.memory.region array. and We don't need to use extend_brk() after fill_memblock_area() So move reserve_brk() early before fill_memblock_area(). -v3: Move find_smp_config early To make sure memblock_find_in_range not find wrong place, if BIOS doesn't put mptable in right place. -v4: Treat RESERVED_KERN as RAM in memblock.memory. and they are already in memblock.reserved already.. use __NOT_KEEP_MEMBLOCK to make sure memblock related code could be freed later. -v5: Generic version __memblock_find_in_range() is going from high to low, and for 32bit active_region for 32bit does include high pages need to replace the limit with memblock.default_alloc_limit, aka get_max_mapped() -v6: Use current_limit instead -v7: check with MEMBLOCK_ERROR instead of -1ULL or -1L -v8: Set memblock_can_resize early to handle EFI with more RAM entries -v9: update after kmemleak changes in mainline Suggested-by: David S. Miller <davem@davemloft.net> Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Suggested-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/Kconfig9
-rw-r--r--arch/x86/include/asm/e820.h14
-rw-r--r--arch/x86/kernel/check.c16
-rw-r--r--arch/x86/kernel/e820.c159
-rw-r--r--arch/x86/kernel/head.c3
-rw-r--r--arch/x86/kernel/head32.c6
-rw-r--r--arch/x86/kernel/head64.c3
-rw-r--r--arch/x86/kernel/mpparse.c5
-rw-r--r--arch/x86/kernel/setup.c46
-rw-r--r--arch/x86/kernel/setup_percpu.c6
-rw-r--r--arch/x86/mm/numa_64.c9
-rw-r--r--mm/bootmem.c3
-rw-r--r--mm/page_alloc.c50
-rw-r--r--mm/sparse-vmemmap.c11
14 files changed, 141 insertions, 199 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index dcb0593b4a66..542bb2610cbb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
27 select HAVE_PERF_EVENTS if (!M386 && !M486) 27 select HAVE_PERF_EVENTS if (!M386 && !M486)
28 select HAVE_IOREMAP_PROT 28 select HAVE_IOREMAP_PROT
29 select HAVE_KPROBES 29 select HAVE_KPROBES
30 select HAVE_MEMBLOCK
30 select ARCH_WANT_OPTIONAL_GPIOLIB 31 select ARCH_WANT_OPTIONAL_GPIOLIB
31 select ARCH_WANT_FRAME_POINTERS 32 select ARCH_WANT_FRAME_POINTERS
32 select HAVE_DMA_ATTRS 33 select HAVE_DMA_ATTRS
@@ -195,9 +196,6 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
195config ARCH_SUPPORTS_DEBUG_PAGEALLOC 196config ARCH_SUPPORTS_DEBUG_PAGEALLOC
196 def_bool y 197 def_bool y
197 198
198config HAVE_EARLY_RES
199 def_bool y
200
201config HAVE_INTEL_TXT 199config HAVE_INTEL_TXT
202 def_bool y 200 def_bool y
203 depends on EXPERIMENTAL && DMAR && ACPI 201 depends on EXPERIMENTAL && DMAR && ACPI
@@ -590,14 +588,13 @@ config NO_BOOTMEM
590 default y 588 default y
591 bool "Disable Bootmem code" 589 bool "Disable Bootmem code"
592 ---help--- 590 ---help---
593 Use early_res directly instead of bootmem before slab is ready. 591 Use memblock directly instead of bootmem before slab is ready.
594 - allocator (buddy) [generic] 592 - allocator (buddy) [generic]
595 - early allocator (bootmem) [generic] 593 - early allocator (bootmem) [generic]
596 - very early allocator (reserve_early*()) [x86] 594 - very early allocator (memblock) [some generic]
597 - very very early allocator (early brk model) [x86] 595 - very very early allocator (early brk model) [x86]
598 So reduce one layer between early allocator to final allocator 596 So reduce one layer between early allocator to final allocator
599 597
600
601config MEMTEST 598config MEMTEST
602 bool "Memtest" 599 bool "Memtest"
603 ---help--- 600 ---help---
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index ec8a52d14ab1..388fed291467 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -117,24 +117,26 @@ extern unsigned long end_user_pfn;
117extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); 117extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
118extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); 118extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
119extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); 119extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
120#include <linux/early_res.h>
121 120
122extern unsigned long e820_end_of_ram_pfn(void); 121extern unsigned long e820_end_of_ram_pfn(void);
123extern unsigned long e820_end_of_low_ram_pfn(void); 122extern unsigned long e820_end_of_low_ram_pfn(void);
124extern int e820_find_active_region(const struct e820entry *ei,
125 unsigned long start_pfn,
126 unsigned long last_pfn,
127 unsigned long *ei_startpfn,
128 unsigned long *ei_endpfn);
129extern void e820_register_active_regions(int nid, unsigned long start_pfn, 123extern void e820_register_active_regions(int nid, unsigned long start_pfn,
130 unsigned long end_pfn); 124 unsigned long end_pfn);
131extern u64 e820_hole_size(u64 start, u64 end); 125extern u64 e820_hole_size(u64 start, u64 end);
126
127extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
128
129void memblock_x86_fill(void);
130
132extern void finish_e820_parsing(void); 131extern void finish_e820_parsing(void);
133extern void e820_reserve_resources(void); 132extern void e820_reserve_resources(void);
134extern void e820_reserve_resources_late(void); 133extern void e820_reserve_resources_late(void);
135extern void setup_memory_map(void); 134extern void setup_memory_map(void);
136extern char *default_machine_specific_memory_setup(void); 135extern char *default_machine_specific_memory_setup(void);
137 136
137void reserve_early(u64 start, u64 end, char *name);
138void free_early(u64 start, u64 end);
139
138/* 140/*
139 * Returns true iff the specified range [s,e) is completely contained inside 141 * Returns true iff the specified range [s,e) is completely contained inside
140 * the ISA region. 142 * the ISA region.
diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c
index fc999e6fc46a..13a389179514 100644
--- a/arch/x86/kernel/check.c
+++ b/arch/x86/kernel/check.c
@@ -2,7 +2,8 @@
2#include <linux/sched.h> 2#include <linux/sched.h>
3#include <linux/kthread.h> 3#include <linux/kthread.h>
4#include <linux/workqueue.h> 4#include <linux/workqueue.h>
5#include <asm/e820.h> 5#include <linux/memblock.h>
6
6#include <asm/proto.h> 7#include <asm/proto.h>
7 8
8/* 9/*
@@ -18,10 +19,12 @@ static int __read_mostly memory_corruption_check = -1;
18static unsigned __read_mostly corruption_check_size = 64*1024; 19static unsigned __read_mostly corruption_check_size = 64*1024;
19static unsigned __read_mostly corruption_check_period = 60; /* seconds */ 20static unsigned __read_mostly corruption_check_period = 60; /* seconds */
20 21
21static struct e820entry scan_areas[MAX_SCAN_AREAS]; 22static struct scan_area {
23 u64 addr;
24 u64 size;
25} scan_areas[MAX_SCAN_AREAS];
22static int num_scan_areas; 26static int num_scan_areas;
23 27
24
25static __init int set_corruption_check(char *arg) 28static __init int set_corruption_check(char *arg)
26{ 29{
27 char *end; 30 char *end;
@@ -81,9 +84,9 @@ void __init setup_bios_corruption_check(void)
81 84
82 while (addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) { 85 while (addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) {
83 u64 size; 86 u64 size;
84 addr = find_e820_area_size(addr, &size, PAGE_SIZE); 87 addr = memblock_x86_find_in_range_size(addr, &size, PAGE_SIZE);
85 88
86 if (!(addr + 1)) 89 if (addr == MEMBLOCK_ERROR)
87 break; 90 break;
88 91
89 if (addr >= corruption_check_size) 92 if (addr >= corruption_check_size)
@@ -92,7 +95,7 @@ void __init setup_bios_corruption_check(void)
92 if ((addr + size) > corruption_check_size) 95 if ((addr + size) > corruption_check_size)
93 size = corruption_check_size - addr; 96 size = corruption_check_size - addr;
94 97
95 e820_update_range(addr, size, E820_RAM, E820_RESERVED); 98 memblock_x86_reserve_range(addr, addr + size, "SCAN RAM");
96 scan_areas[num_scan_areas].addr = addr; 99 scan_areas[num_scan_areas].addr = addr;
97 scan_areas[num_scan_areas].size = size; 100 scan_areas[num_scan_areas].size = size;
98 num_scan_areas++; 101 num_scan_areas++;
@@ -105,7 +108,6 @@ void __init setup_bios_corruption_check(void)
105 108
106 printk(KERN_INFO "Scanning %d areas for low memory corruption\n", 109 printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
107 num_scan_areas); 110 num_scan_areas);
108 update_e820();
109} 111}
110 112
111 113
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 0d6fc71bedb1..a9221d18a5ed 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -15,6 +15,7 @@
15#include <linux/pfn.h> 15#include <linux/pfn.h>
16#include <linux/suspend.h> 16#include <linux/suspend.h>
17#include <linux/firmware-map.h> 17#include <linux/firmware-map.h>
18#include <linux/memblock.h>
18 19
19#include <asm/e820.h> 20#include <asm/e820.h>
20#include <asm/proto.h> 21#include <asm/proto.h>
@@ -742,69 +743,29 @@ core_initcall(e820_mark_nvs_memory);
742 */ 743 */
743u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align) 744u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
744{ 745{
745 int i; 746 u64 mem = memblock_find_in_range(start, end, size, align);
746
747 for (i = 0; i < e820.nr_map; i++) {
748 struct e820entry *ei = &e820.map[i];
749 u64 addr;
750 u64 ei_start, ei_last;
751 747
752 if (ei->type != E820_RAM) 748 if (mem == MEMBLOCK_ERROR)
753 continue; 749 return -1ULL;
754
755 ei_last = ei->addr + ei->size;
756 ei_start = ei->addr;
757 addr = find_early_area(ei_start, ei_last, start, end,
758 size, align);
759
760 if (addr != -1ULL)
761 return addr;
762 }
763 return -1ULL;
764}
765 750
766u64 __init find_fw_memmap_area(u64 start, u64 end, u64 size, u64 align) 751 return mem;
767{
768 return find_e820_area(start, end, size, align);
769} 752}
770 753
771u64 __init get_max_mapped(void)
772{
773 u64 end = max_pfn_mapped;
774
775 end <<= PAGE_SHIFT;
776
777 return end;
778}
779/* 754/*
780 * Find next free range after *start 755 * Find next free range after *start
781 */ 756 */
782u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align) 757u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
783{ 758{
784 int i; 759 u64 mem = memblock_x86_find_in_range_size(start, sizep, align);
785 760
786 for (i = 0; i < e820.nr_map; i++) { 761 if (mem == MEMBLOCK_ERROR)
787 struct e820entry *ei = &e820.map[i]; 762 return -1ULL
788 u64 addr;
789 u64 ei_start, ei_last;
790
791 if (ei->type != E820_RAM)
792 continue;
793
794 ei_last = ei->addr + ei->size;
795 ei_start = ei->addr;
796 addr = find_early_area_size(ei_start, ei_last, start,
797 sizep, align);
798 763
799 if (addr != -1ULL) 764 return mem;
800 return addr;
801 }
802
803 return -1ULL;
804} 765}
805 766
806/* 767/*
807 * pre allocated 4k and reserved it in e820 768 * pre allocated 4k and reserved it in memblock and e820_saved
808 */ 769 */
809u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) 770u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
810{ 771{
@@ -813,8 +774,8 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
813 u64 start; 774 u64 start;
814 775
815 for (start = startt; ; start += size) { 776 for (start = startt; ; start += size) {
816 start = find_e820_area_size(start, &size, align); 777 start = memblock_x86_find_in_range_size(start, &size, align);
817 if (!(start + 1)) 778 if (start == MEMBLOCK_ERROR)
818 return 0; 779 return 0;
819 if (size >= sizet) 780 if (size >= sizet)
820 break; 781 break;
@@ -830,10 +791,9 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
830 addr = round_down(start + size - sizet, align); 791 addr = round_down(start + size - sizet, align);
831 if (addr < start) 792 if (addr < start)
832 return 0; 793 return 0;
833 e820_update_range(addr, sizet, E820_RAM, E820_RESERVED); 794 memblock_x86_reserve_range(addr, addr + sizet, "new next");
834 e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED); 795 e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
835 printk(KERN_INFO "update e820 for early_reserve_e820\n"); 796 printk(KERN_INFO "update e820_saved for early_reserve_e820\n");
836 update_e820();
837 update_e820_saved(); 797 update_e820_saved();
838 798
839 return addr; 799 return addr;
@@ -895,52 +855,12 @@ unsigned long __init e820_end_of_low_ram_pfn(void)
895{ 855{
896 return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM); 856 return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
897} 857}
898/*
899 * Finds an active region in the address range from start_pfn to last_pfn and
900 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
901 */
902int __init e820_find_active_region(const struct e820entry *ei,
903 unsigned long start_pfn,
904 unsigned long last_pfn,
905 unsigned long *ei_startpfn,
906 unsigned long *ei_endpfn)
907{
908 u64 align = PAGE_SIZE;
909
910 *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
911 *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
912
913 /* Skip map entries smaller than a page */
914 if (*ei_startpfn >= *ei_endpfn)
915 return 0;
916
917 /* Skip if map is outside the node */
918 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
919 *ei_startpfn >= last_pfn)
920 return 0;
921
922 /* Check for overlaps */
923 if (*ei_startpfn < start_pfn)
924 *ei_startpfn = start_pfn;
925 if (*ei_endpfn > last_pfn)
926 *ei_endpfn = last_pfn;
927
928 return 1;
929}
930 858
931/* Walk the e820 map and register active regions within a node */ 859/* Walk the e820 map and register active regions within a node */
932void __init e820_register_active_regions(int nid, unsigned long start_pfn, 860void __init e820_register_active_regions(int nid, unsigned long start_pfn,
933 unsigned long last_pfn) 861 unsigned long last_pfn)
934{ 862{
935 unsigned long ei_startpfn; 863 memblock_x86_register_active_regions(nid, start_pfn, last_pfn);
936 unsigned long ei_endpfn;
937 int i;
938
939 for (i = 0; i < e820.nr_map; i++)
940 if (e820_find_active_region(&e820.map[i],
941 start_pfn, last_pfn,
942 &ei_startpfn, &ei_endpfn))
943 add_active_range(nid, ei_startpfn, ei_endpfn);
944} 864}
945 865
946/* 866/*
@@ -950,18 +870,16 @@ void __init e820_register_active_regions(int nid, unsigned long start_pfn,
950 */ 870 */
951u64 __init e820_hole_size(u64 start, u64 end) 871u64 __init e820_hole_size(u64 start, u64 end)
952{ 872{
953 unsigned long start_pfn = start >> PAGE_SHIFT; 873 return memblock_x86_hole_size(start, end);
954 unsigned long last_pfn = end >> PAGE_SHIFT; 874}
955 unsigned long ei_startpfn, ei_endpfn, ram = 0;
956 int i;
957 875
958 for (i = 0; i < e820.nr_map; i++) { 876void reserve_early(u64 start, u64 end, char *name)
959 if (e820_find_active_region(&e820.map[i], 877{
960 start_pfn, last_pfn, 878 memblock_x86_reserve_range(start, end, name);
961 &ei_startpfn, &ei_endpfn)) 879}
962 ram += ei_endpfn - ei_startpfn; 880void free_early(u64 start, u64 end)
963 } 881{
964 return end - start - ((u64)ram << PAGE_SHIFT); 882 memblock_x86_free_range(start, end);
965} 883}
966 884
967static void early_panic(char *msg) 885static void early_panic(char *msg)
@@ -1210,3 +1128,32 @@ void __init setup_memory_map(void)
1210 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 1128 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
1211 e820_print_map(who); 1129 e820_print_map(who);
1212} 1130}
1131
1132void __init memblock_x86_fill(void)
1133{
1134 int i;
1135 u64 end;
1136
1137 /*
1138 * EFI may have more than 128 entries
1139 * We are safe to enable resizing, beause memblock_x86_fill()
1140 * is rather later for x86
1141 */
1142 memblock_can_resize = 1;
1143
1144 for (i = 0; i < e820.nr_map; i++) {
1145 struct e820entry *ei = &e820.map[i];
1146
1147 end = ei->addr + ei->size;
1148 if (end != (resource_size_t)end)
1149 continue;
1150
1151 if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
1152 continue;
1153
1154 memblock_add(ei->addr, ei->size);
1155 }
1156
1157 memblock_analyze();
1158 memblock_dump_all();
1159}
diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c
index 3e66bd364a9d..af0699ba48cf 100644
--- a/arch/x86/kernel/head.c
+++ b/arch/x86/kernel/head.c
@@ -1,5 +1,6 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/init.h> 2#include <linux/init.h>
3#include <linux/memblock.h>
3 4
4#include <asm/setup.h> 5#include <asm/setup.h>
5#include <asm/bios_ebda.h> 6#include <asm/bios_ebda.h>
@@ -51,5 +52,5 @@ void __init reserve_ebda_region(void)
51 lowmem = 0x9f000; 52 lowmem = 0x9f000;
52 53
53 /* reserve all memory between lowmem and the 1MB mark */ 54 /* reserve all memory between lowmem and the 1MB mark */
54 reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved"); 55 memblock_x86_reserve_range(lowmem, 0x100000, "* BIOS reserved");
55} 56}
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index b2e246037392..da60aa8a850f 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -8,6 +8,7 @@
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/start_kernel.h> 9#include <linux/start_kernel.h>
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/memblock.h>
11 12
12#include <asm/setup.h> 13#include <asm/setup.h>
13#include <asm/sections.h> 14#include <asm/sections.h>
@@ -30,14 +31,15 @@ static void __init i386_default_early_setup(void)
30 31
31void __init i386_start_kernel(void) 32void __init i386_start_kernel(void)
32{ 33{
34 memblock_init();
35
33#ifdef CONFIG_X86_TRAMPOLINE 36#ifdef CONFIG_X86_TRAMPOLINE
34 /* 37 /*
35 * But first pinch a few for the stack/trampoline stuff 38 * But first pinch a few for the stack/trampoline stuff
36 * FIXME: Don't need the extra page at 4K, but need to fix 39 * FIXME: Don't need the extra page at 4K, but need to fix
37 * trampoline before removing it. (see the GDT stuff) 40 * trampoline before removing it. (see the GDT stuff)
38 */ 41 */
39 reserve_early_overlap_ok(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, 42 memblock_x86_reserve_range(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
40 "EX TRAMPOLINE");
41#endif 43#endif
42 44
43 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); 45 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 7147143fd614..8ee930fdeeb9 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -12,6 +12,7 @@
12#include <linux/percpu.h> 12#include <linux/percpu.h>
13#include <linux/start_kernel.h> 13#include <linux/start_kernel.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/memblock.h>
15 16
16#include <asm/processor.h> 17#include <asm/processor.h>
17#include <asm/proto.h> 18#include <asm/proto.h>
@@ -98,6 +99,8 @@ void __init x86_64_start_reservations(char *real_mode_data)
98{ 99{
99 copy_bootdata(__va(real_mode_data)); 100 copy_bootdata(__va(real_mode_data));
100 101
102 memblock_init();
103
101 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); 104 reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
102 105
103#ifdef CONFIG_BLK_DEV_INITRD 106#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index d86dbf7e54be..8252545ae6f3 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/memblock.h>
14#include <linux/kernel_stat.h> 15#include <linux/kernel_stat.h>
15#include <linux/mc146818rtc.h> 16#include <linux/mc146818rtc.h>
16#include <linux/bitops.h> 17#include <linux/bitops.h>
@@ -641,7 +642,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf)
641{ 642{
642 unsigned long size = get_mpc_size(mpf->physptr); 643 unsigned long size = get_mpc_size(mpf->physptr);
643 644
644 reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc"); 645 memblock_x86_reserve_range(mpf->physptr, mpf->physptr+size, "* MP-table mpc");
645} 646}
646 647
647static int __init smp_scan_config(unsigned long base, unsigned long length) 648static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -670,7 +671,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
670 mpf, (u64)virt_to_phys(mpf)); 671 mpf, (u64)virt_to_phys(mpf));
671 672
672 mem = virt_to_phys(mpf); 673 mem = virt_to_phys(mpf);
673 reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf"); 674 memblock_x86_reserve_range(mem, mem + sizeof(*mpf), "* MP-table mpf");
674 if (mpf->physptr) 675 if (mpf->physptr)
675 smp_reserve_memory(mpf); 676 smp_reserve_memory(mpf);
676 677
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index b4ae4acbd031..bbe0aaf77494 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -31,6 +31,7 @@
31#include <linux/apm_bios.h> 31#include <linux/apm_bios.h>
32#include <linux/initrd.h> 32#include <linux/initrd.h>
33#include <linux/bootmem.h> 33#include <linux/bootmem.h>
34#include <linux/memblock.h>
34#include <linux/seq_file.h> 35#include <linux/seq_file.h>
35#include <linux/console.h> 36#include <linux/console.h>
36#include <linux/mca.h> 37#include <linux/mca.h>
@@ -614,7 +615,7 @@ static __init void reserve_ibft_region(void)
614 addr = find_ibft_region(&size); 615 addr = find_ibft_region(&size);
615 616
616 if (size) 617 if (size)
617 reserve_early_overlap_ok(addr, addr + size, "ibft"); 618 memblock_x86_reserve_range(addr, addr + size, "* ibft");
618} 619}
619 620
620#ifdef CONFIG_X86_RESERVE_LOW_64K 621#ifdef CONFIG_X86_RESERVE_LOW_64K
@@ -708,6 +709,15 @@ static void __init trim_bios_range(void)
708 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); 709 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
709} 710}
710 711
712static u64 __init get_max_mapped(void)
713{
714 u64 end = max_pfn_mapped;
715
716 end <<= PAGE_SHIFT;
717
718 return end;
719}
720
711/* 721/*
712 * Determine if we were loaded by an EFI loader. If so, then we have also been 722 * Determine if we were loaded by an EFI loader. If so, then we have also been
713 * passed the efi memmap, systab, etc., so we should use these data structures 723 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -891,8 +901,6 @@ void __init setup_arch(char **cmdline_p)
891 */ 901 */
892 max_pfn = e820_end_of_ram_pfn(); 902 max_pfn = e820_end_of_ram_pfn();
893 903
894 /* preallocate 4k for mptable mpc */
895 early_reserve_e820_mpc_new();
896 /* update e820 for memory not covered by WB MTRRs */ 904 /* update e820 for memory not covered by WB MTRRs */
897 mtrr_bp_init(); 905 mtrr_bp_init();
898 if (mtrr_trim_uncached_memory(max_pfn)) 906 if (mtrr_trim_uncached_memory(max_pfn))
@@ -917,15 +925,6 @@ void __init setup_arch(char **cmdline_p)
917 max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT; 925 max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
918#endif 926#endif
919 927
920#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
921 setup_bios_corruption_check();
922#endif
923
924 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
925 max_pfn_mapped<<PAGE_SHIFT);
926
927 reserve_brk();
928
929 /* 928 /*
930 * Find and reserve possible boot-time SMP configuration: 929 * Find and reserve possible boot-time SMP configuration:
931 */ 930 */
@@ -933,6 +932,26 @@ void __init setup_arch(char **cmdline_p)
933 932
934 reserve_ibft_region(); 933 reserve_ibft_region();
935 934
935 /*
936 * Need to conclude brk, before memblock_x86_fill()
937 * it could use memblock_find_in_range, could overlap with
938 * brk area.
939 */
940 reserve_brk();
941
942 memblock.current_limit = get_max_mapped();
943 memblock_x86_fill();
944
945 /* preallocate 4k for mptable mpc */
946 early_reserve_e820_mpc_new();
947
948#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
949 setup_bios_corruption_check();
950#endif
951
952 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
953 max_pfn_mapped<<PAGE_SHIFT);
954
936 reserve_trampoline_memory(); 955 reserve_trampoline_memory();
937 956
938#ifdef CONFIG_ACPI_SLEEP 957#ifdef CONFIG_ACPI_SLEEP
@@ -956,6 +975,7 @@ void __init setup_arch(char **cmdline_p)
956 max_low_pfn = max_pfn; 975 max_low_pfn = max_pfn;
957 } 976 }
958#endif 977#endif
978 memblock.current_limit = get_max_mapped();
959 979
960 /* 980 /*
961 * NOTE: On x86-32, only from this point on, fixmaps are ready for use. 981 * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
@@ -995,7 +1015,7 @@ void __init setup_arch(char **cmdline_p)
995 1015
996 initmem_init(0, max_pfn, acpi, k8); 1016 initmem_init(0, max_pfn, acpi, k8);
997#ifndef CONFIG_NO_BOOTMEM 1017#ifndef CONFIG_NO_BOOTMEM
998 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); 1018 memblock_x86_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
999#endif 1019#endif
1000 1020
1001 dma32_reserve_bootmem(); 1021 dma32_reserve_bootmem();
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index a60df9ae6454..42e2633f369e 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -131,13 +131,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
131 131
132static void __init pcpu_fc_free(void *ptr, size_t size) 132static void __init pcpu_fc_free(void *ptr, size_t size)
133{ 133{
134#ifdef CONFIG_NO_BOOTMEM
135 u64 start = __pa(ptr);
136 u64 end = start + size;
137 free_early_partial(start, end);
138#else
139 free_bootmem(__pa(ptr), size); 134 free_bootmem(__pa(ptr), size);
140#endif
141} 135}
142 136
143static int __init pcpu_cpu_distance(unsigned int from, unsigned int to) 137static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index a7bcc23ef96c..3d54f9f95d46 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -7,6 +7,7 @@
7#include <linux/string.h> 7#include <linux/string.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/bootmem.h> 9#include <linux/bootmem.h>
10#include <linux/memblock.h>
10#include <linux/mmzone.h> 11#include <linux/mmzone.h>
11#include <linux/ctype.h> 12#include <linux/ctype.h>
12#include <linux/module.h> 13#include <linux/module.h>
@@ -171,8 +172,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
171 if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) && 172 if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
172 end > (MAX_DMA32_PFN<<PAGE_SHIFT)) 173 end > (MAX_DMA32_PFN<<PAGE_SHIFT))
173 start = MAX_DMA32_PFN<<PAGE_SHIFT; 174 start = MAX_DMA32_PFN<<PAGE_SHIFT;
174 mem = find_e820_area(start, end, size, align); 175 mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
175 if (mem != -1L) 176 if (mem != MEMBLOCK_ERROR)
176 return __va(mem); 177 return __va(mem);
177 178
178 /* extend the search scope */ 179 /* extend the search scope */
@@ -181,8 +182,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
181 start = MAX_DMA32_PFN<<PAGE_SHIFT; 182 start = MAX_DMA32_PFN<<PAGE_SHIFT;
182 else 183 else
183 start = MAX_DMA_PFN<<PAGE_SHIFT; 184 start = MAX_DMA_PFN<<PAGE_SHIFT;
184 mem = find_e820_area(start, end, size, align); 185 mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
185 if (mem != -1L) 186 if (mem != MEMBLOCK_ERROR)
186 return __va(mem); 187 return __va(mem);
187 188
188 printk(KERN_ERR "Cannot find %lu bytes in node %d\n", 189 printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
diff --git a/mm/bootmem.c b/mm/bootmem.c
index bde170dd2fde..fda01a2c31af 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kmemleak.h> 16#include <linux/kmemleak.h>
17#include <linux/range.h> 17#include <linux/range.h>
18#include <linux/memblock.h>
18 19
19#include <asm/bug.h> 20#include <asm/bug.h>
20#include <asm/io.h> 21#include <asm/io.h>
@@ -434,6 +435,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
434 unsigned long size) 435 unsigned long size)
435{ 436{
436#ifdef CONFIG_NO_BOOTMEM 437#ifdef CONFIG_NO_BOOTMEM
438 kmemleak_free_part(__va(physaddr), size);
437 free_early(physaddr, physaddr + size); 439 free_early(physaddr, physaddr + size);
438#else 440#else
439 unsigned long start, end; 441 unsigned long start, end;
@@ -459,6 +461,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
459void __init free_bootmem(unsigned long addr, unsigned long size) 461void __init free_bootmem(unsigned long addr, unsigned long size)
460{ 462{
461#ifdef CONFIG_NO_BOOTMEM 463#ifdef CONFIG_NO_BOOTMEM
464 kmemleak_free_part(__va(addr), size);
462 free_early(addr, addr + size); 465 free_early(addr, addr + size);
463#else 466#else
464 unsigned long start, end; 467 unsigned long start, end;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8c9b34674d83..f2cd7450fa76 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3667,46 +3667,26 @@ int __init add_from_early_node_map(struct range *range, int az,
3667void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, 3667void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
3668 u64 goal, u64 limit) 3668 u64 goal, u64 limit)
3669{ 3669{
3670 int i;
3671 void *ptr; 3670 void *ptr;
3671 u64 addr;
3672 3672
3673 if (limit > get_max_mapped()) 3673 if (limit > memblock.current_limit)
3674 limit = get_max_mapped(); 3674 limit = memblock.current_limit;
3675 3675
3676 /* need to go over early_node_map to find out good range for node */ 3676 addr = find_memory_core_early(nid, size, align, goal, limit);
3677 for_each_active_range_index_in_nid(i, nid) {
3678 u64 addr;
3679 u64 ei_start, ei_last;
3680 3677
3681 ei_last = early_node_map[i].end_pfn; 3678 if (addr == MEMBLOCK_ERROR)
3682 ei_last <<= PAGE_SHIFT; 3679 return NULL;
3683 ei_start = early_node_map[i].start_pfn;
3684 ei_start <<= PAGE_SHIFT;
3685 addr = find_early_area(ei_start, ei_last,
3686 goal, limit, size, align);
3687
3688 if (addr == -1ULL)
3689 continue;
3690
3691#if 0
3692 printk(KERN_DEBUG "alloc (nid=%d %llx - %llx) (%llx - %llx) %llx %llx => %llx\n",
3693 nid,
3694 ei_start, ei_last, goal, limit, size,
3695 align, addr);
3696#endif
3697
3698 ptr = phys_to_virt(addr);
3699 memset(ptr, 0, size);
3700 reserve_early_without_check(addr, addr + size, "BOOTMEM");
3701 /*
3702 * The min_count is set to 0 so that bootmem allocated blocks
3703 * are never reported as leaks.
3704 */
3705 kmemleak_alloc(ptr, size, 0, 0);
3706 return ptr;
3707 }
3708 3680
3709 return NULL; 3681 ptr = phys_to_virt(addr);
3682 memset(ptr, 0, size);
3683 memblock_x86_reserve_range(addr, addr + size, "BOOTMEM");
3684 /*
3685 * The min_count is set to 0 so that bootmem allocated blocks
3686 * are never reported as leaks.
3687 */
3688 kmemleak_alloc(ptr, size, 0, 0);
3689 return ptr;
3710} 3690}
3711#endif 3691#endif
3712 3692
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index aa33fd67fa41..29d6cbffb283 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -220,18 +220,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
220 220
221 if (vmemmap_buf_start) { 221 if (vmemmap_buf_start) {
222 /* need to free left buf */ 222 /* need to free left buf */
223#ifdef CONFIG_NO_BOOTMEM
224 free_early(__pa(vmemmap_buf_start), __pa(vmemmap_buf_end));
225 if (vmemmap_buf_start < vmemmap_buf) {
226 char name[15];
227
228 snprintf(name, sizeof(name), "MEMMAP %d", nodeid);
229 reserve_early_without_check(__pa(vmemmap_buf_start),
230 __pa(vmemmap_buf), name);
231 }
232#else
233 free_bootmem(__pa(vmemmap_buf), vmemmap_buf_end - vmemmap_buf); 223 free_bootmem(__pa(vmemmap_buf), vmemmap_buf_end - vmemmap_buf);
234#endif
235 vmemmap_buf = NULL; 224 vmemmap_buf = NULL;
236 vmemmap_buf_end = NULL; 225 vmemmap_buf_end = NULL;
237 } 226 }