diff options
| author | Yinghai Lu <yinghai@kernel.org> | 2010-08-25 16:39:17 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2010-08-27 14:12:29 -0400 |
| commit | 72d7c3b33c980843e756681fb4867dc1efd62a76 (patch) | |
| tree | 9607345d9fa055dd501aacf0772258fb72897035 | |
| parent | 301ff3e88ef9ff4bdb92f36a3e6170fce4c9dd34 (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/Kconfig | 9 | ||||
| -rw-r--r-- | arch/x86/include/asm/e820.h | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/check.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/e820.c | 159 | ||||
| -rw-r--r-- | arch/x86/kernel/head.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/head32.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/head64.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/mpparse.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 46 | ||||
| -rw-r--r-- | arch/x86/kernel/setup_percpu.c | 6 | ||||
| -rw-r--r-- | arch/x86/mm/numa_64.c | 9 | ||||
| -rw-r--r-- | mm/bootmem.c | 3 | ||||
| -rw-r--r-- | mm/page_alloc.c | 50 | ||||
| -rw-r--r-- | mm/sparse-vmemmap.c | 11 |
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 | |||
| 195 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC | 196 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 196 | def_bool y | 197 | def_bool y |
| 197 | 198 | ||
| 198 | config HAVE_EARLY_RES | ||
| 199 | def_bool y | ||
| 200 | |||
| 201 | config HAVE_INTEL_TXT | 199 | config 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 | |||
| 601 | config MEMTEST | 598 | config 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; | |||
| 117 | extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); | 117 | extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); |
| 118 | extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); | 118 | extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); |
| 119 | extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); | 119 | extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); |
| 120 | #include <linux/early_res.h> | ||
| 121 | 120 | ||
| 122 | extern unsigned long e820_end_of_ram_pfn(void); | 121 | extern unsigned long e820_end_of_ram_pfn(void); |
| 123 | extern unsigned long e820_end_of_low_ram_pfn(void); | 122 | extern unsigned long e820_end_of_low_ram_pfn(void); |
| 124 | extern 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); | ||
| 129 | extern void e820_register_active_regions(int nid, unsigned long start_pfn, | 123 | extern void e820_register_active_regions(int nid, unsigned long start_pfn, |
| 130 | unsigned long end_pfn); | 124 | unsigned long end_pfn); |
| 131 | extern u64 e820_hole_size(u64 start, u64 end); | 125 | extern u64 e820_hole_size(u64 start, u64 end); |
| 126 | |||
| 127 | extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); | ||
| 128 | |||
| 129 | void memblock_x86_fill(void); | ||
| 130 | |||
| 132 | extern void finish_e820_parsing(void); | 131 | extern void finish_e820_parsing(void); |
| 133 | extern void e820_reserve_resources(void); | 132 | extern void e820_reserve_resources(void); |
| 134 | extern void e820_reserve_resources_late(void); | 133 | extern void e820_reserve_resources_late(void); |
| 135 | extern void setup_memory_map(void); | 134 | extern void setup_memory_map(void); |
| 136 | extern char *default_machine_specific_memory_setup(void); | 135 | extern char *default_machine_specific_memory_setup(void); |
| 137 | 136 | ||
| 137 | void reserve_early(u64 start, u64 end, char *name); | ||
| 138 | void 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; | |||
| 18 | static unsigned __read_mostly corruption_check_size = 64*1024; | 19 | static unsigned __read_mostly corruption_check_size = 64*1024; |
| 19 | static unsigned __read_mostly corruption_check_period = 60; /* seconds */ | 20 | static unsigned __read_mostly corruption_check_period = 60; /* seconds */ |
| 20 | 21 | ||
| 21 | static struct e820entry scan_areas[MAX_SCAN_AREAS]; | 22 | static struct scan_area { |
| 23 | u64 addr; | ||
| 24 | u64 size; | ||
| 25 | } scan_areas[MAX_SCAN_AREAS]; | ||
| 22 | static int num_scan_areas; | 26 | static int num_scan_areas; |
| 23 | 27 | ||
| 24 | |||
| 25 | static __init int set_corruption_check(char *arg) | 28 | static __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 | */ |
| 743 | u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align) | 744 | u64 __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 | ||
| 766 | u64 __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 | ||
| 771 | u64 __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 | */ |
| 782 | u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align) | 757 | u64 __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 | */ |
| 809 | u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) | 770 | u64 __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 | */ | ||
| 902 | int __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 */ |
| 932 | void __init e820_register_active_regions(int nid, unsigned long start_pfn, | 860 | void __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 | */ |
| 951 | u64 __init e820_hole_size(u64 start, u64 end) | 871 | u64 __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++) { | 876 | void 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; | 880 | void 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 | ||
| 967 | static void early_panic(char *msg) | 885 | static 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 | |||
| 1132 | void __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 | ||
| 31 | void __init i386_start_kernel(void) | 32 | void __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 | ||
| 647 | static int __init smp_scan_config(unsigned long base, unsigned long length) | 648 | static 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 | ||
| 712 | static 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 | ||
| 132 | static void __init pcpu_fc_free(void *ptr, size_t size) | 132 | static 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 | ||
| 143 | static int __init pcpu_cpu_distance(unsigned int from, unsigned int to) | 137 | static 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, | |||
| 459 | void __init free_bootmem(unsigned long addr, unsigned long size) | 461 | void __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, | |||
| 3667 | void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, | 3667 | void * __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 | } |
