Use memblock with x86
Subsystems (11)
cover Use memblock with x86
New memblock could be used to replace early_res in x86.
Suggested by: David, Ben, and Thomas
-v25: update to mainline with kmemleak fix on nobootmem
also rename lmb to memblock alread in mainline
-v26: according to Linus and hpa, seperate the big patchset to small ones.
-v27: rebase to Ben's powerpc/memblock
add memblock_free_reserved_regions() so don't need to export init regions
this one is x86 related, finally we can remove bootmem code in x86 and early_res code.
Thanks
Yinghai Lu
[PATCH 01/17] memblock: Add memblock_free/reserve_reserved_regions()
[PATCH 02/17] x86, memblock: Add memblock_x86_find_in_range_size()
[PATCH 03/17] bootmem, x86: Add weak version of reserve_bootmem_generic
[PATCH 04/17] x86, memblock: Add memblock_x86_to_bootmem()
[PATCH 05/17] x86,memblock: Add memblock_x86_reserve_range/memblock_x86_free_range
[PATCH 06/17] x86, memblock: Add get_free_all_memory_range()
[PATCH 07/17] x86, memblock: Add memblock_x86_register_active_regions() and memblock_x86_hole_size() [PATCH 08/17] memblock: Add find_memory_core_early()
[PATCH 09/17] x86, memblock: Add memblock_x86_find_in_range_node()
[PATCH 10/17] x86, memblock: Add memblock_x86_free_memory_in_range()
[PATCH 11/17] x86, memblock: Add memblock_x86_memory_in_range()
[PATCH 12/17] x86, memblock: Use memblock_debug to control debug message print out
[PATCH 13/17] x86: Use memblock to replace early_res
[PATCH 14/17] x86: Replace e820_/_early string with memblock_
[PATCH 15/17] x86: Remove not used early_res code
[PATCH 16/17] x86, memblock: Use memblock_memory_size()/memblock_free_memory_size() to get correct dma_reserve [PATCH 17/17] x86: remove old bootmem code
arch/x86/Kconfig | 15 +- arch/x86/include/asm/e820.h | 20 +- arch/x86/include/asm/efi.h | 2 +- arch/x86/include/asm/memblock.h | 21 ++ arch/x86/kernel/acpi/sleep.c | 9 +- arch/x86/kernel/apic/numaq_32.c | 3 +- arch/x86/kernel/check.c | 16 +- arch/x86/kernel/e820.c | 192 ++++--------- arch/x86/kernel/efi.c | 5 +- arch/x86/kernel/head.c | 3 +- arch/x86/kernel/head32.c | 10 +- arch/x86/kernel/head64.c | 7 +- arch/x86/kernel/mpparse.c | 5 +- arch/x86/kernel/setup.c | 78 +++-- arch/x86/kernel/setup_percpu.c | 6 - arch/x86/kernel/trampoline.c | 10 +- arch/x86/mm/Makefile | 2 + arch/x86/mm/init.c | 10 +- arch/x86/mm/init_32.c | 66 +----- arch/x86/mm/init_64.c | 67 +----- arch/x86/mm/k8topology_64.c | 4 +- arch/x86/mm/memblock.c | 355 +++++++++++++++++++++++ arch/x86/mm/memtest.c | 7 +- arch/x86/mm/numa_32.c | 28 +- arch/x86/mm/numa_64.c | 84 ++----- arch/x86/mm/srat_32.c | 3 +- arch/x86/mm/srat_64.c | 11 +- arch/x86/xen/mmu.c | 5 +- arch/x86/xen/setup.c | 3 +- include/linux/early_res.h | 23 -- include/linux/memblock.h | 2 + include/linux/mm.h | 2 + kernel/Makefile | 1 - kernel/early_res.c | 590 --------------------------------------- mm/bootmem.c | 13 +- mm/memblock.c | 24 ++ mm/page_alloc.c | 86 ++++--- mm/sparse-vmemmap.c | 11 - 38 files changed, 677 insertions(+), 1122 deletions(-) create mode 100644 arch/x86/include/asm/memblock.h create mode 100644 arch/x86/mm/memblock.c delete mode 100644 include/linux/early_res.h delete mode 100644 kernel/early_res.c
PATCH 1/17 memblock: Add memblock_free/reserve_reserved_regions()
So we can avoid export memblock_reserved_init_regions() Suggested by Ben.
--- include/linux/memblock.h | 2 ++ mm/memblock.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)
include/linux/memblock.h +2 -0
@@ -48,6 +48,8 @@ extern int memblock_can_resize; if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)u64 memblock_find_in_range (u64 start,u64 end,u64 size,u64 align); +int memblock_free_reserved_regions (void ); +int memblock_reserve_reserved_regions (void );extern void __init memblock_init (void );extern void __init memblock_analyze (void );
mm/memblock.c +24 -0
@@ -170,6 +170,30 @@ u64 __init_memblock memblock_find_in_range(u64 start, u64 end, u64 size, u64 alireturn memblock_find_base (size, align, start, end); } +/* +* Free memblock.reserved.regions +*/ +int memblock_free_reserved_regions (void ) +{ +if (memblock.reserved.regions == memblock_reserved_init_regions) +return 0 ; + +return memblock_free (__pa (memblock.reserved.regions), +sizeof (struct memblock_region ) * memblock.reserved.max); +} + +/* +* Reserve memblock.reserved.regions +*/ +int memblock_reserve_reserved_regions (void ) +{ +if (memblock.reserved.regions == memblock_reserved_init_regions) +return 0 ; + +return memblock_reserve (__pa (memblock.reserved.regions), +sizeof (struct memblock_region ) * memblock.reserved.max); +} + static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r) {unsigned long i;
Signature · 1 line
1.6.4.2
PATCH 1/17 memblock: Add memblock_free/reserve_reserved_regions()
In reply to Yinghai LuSo we can avoid export memblock_reserved_init_regions() Suggested by Ben.
-v2: use __init_memblock attribute
--- include/linux/memblock.h | 2 ++ mm/memblock.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+)
include/linux/memblock.h +2 -0
@@ -48,6 +48,8 @@ extern int memblock_can_resize; if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)u64 memblock_find_in_range (u64 start,u64 end,u64 size,u64 align); +int memblock_free_reserved_regions (void ); +int memblock_reserve_reserved_regions (void );extern void __init memblock_init (void );extern void __init memblock_analyze (void );
mm/memblock.c +24 -0
@@ -170,6 +170,30 @@ u64 __init_memblock memblock_find_in_ranreturn memblock_find_base (size, align, start, end); } +/* +* Free memblock.reserved.regions +*/ +int __init_memblock memblock_free_reserved_regions(void) +{ +if (memblock.reserved.regions == memblock_reserved_init_regions) +return 0 ; + +return memblock_free (__pa (memblock.reserved.regions), +sizeof (struct memblock_region ) * memblock.reserved.max); +} + +/* +* Reserve memblock.reserved.regions +*/ +int __init_memblock memblock_reserve_reserved_regions(void) +{ +if (memblock.reserved.regions == memblock_reserved_init_regions) +return 0 ; + +return memblock_reserve (__pa (memblock.reserved.regions), +sizeof (struct memblock_region ) * memblock.reserved.max); +} + static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r) {unsigned long i;
PATCH 2/17 x86, memblock: Add memblock_x86_find_in_range_size()
In reply to Yinghai Lusize is returned according free range.
Will be used to find free ranges for early_memtest and memory corruption check
Do not mess it up with lib/memblock.c yet.
--- arch/x86/include/asm/memblock.h | 8 ++++ arch/x86/mm/Makefile | 2 + arch/x86/mm/memblock.c | 88 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 0 deletions(-) create mode 100644 arch/x86/include/asm/memblock.h create mode 100644 arch/x86/mm/memblock.c
arch/x86/include/asm/memblock.h new file +8 -0
@@ -0,0 +1,8 @@ +#ifndef _X86_MEMBLOCK_H +#define _X86_MEMBLOCK_H + +#define ARCH_DISCARD_MEMBLOCK + +u64 memblock_x86_find_in_range_size (u64 start,u64 *sizep,u64 align); + +#endif
arch/x86/mm/Makefile +2 -0
@@ -26,4 +26,6 @@ obj-$(CONFIG_NUMA) += numa.o numa_$(BITS).o obj-$(CONFIG_K8_NUMA) += k8topology_64.o obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o +obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o + obj-$(CONFIG_MEMTEST) += memtest.o
arch/x86/mm/memblock.c new file +88 -0
88 lines not on this page · raw message
Signature · 1 line
1.6.4.2
PATCH 3/17 bootmem, x86: Add weak version of reserve_bootmem_generic
In reply to Yinghai LuIt will be used memblock_x86_to_bootmem converting
It is an wrapper for reserve_bootmem, and x86 64bit is using special one.
Also clean up that version for x86_64. We don't need to take care of numa path for that, bootmem can handle it how
--- arch/x86/mm/init_32.c | 6 ------ arch/x86/mm/init_64.c | 20 ++------------------ mm/bootmem.c | 6 ++++++ 3 files changed, 8 insertions(+), 24 deletions(-)
arch/x86/mm/init_32.c +0 -6
@@ -1069,9 +1069,3 @@ void mark_rodata_ro(void) #endif }#endif - -int __init reserve_bootmem_generic (unsigned long phys,unsigned long len, -int flags) -{ -return reserve_bootmem (phys, len, flags); -}
arch/x86/mm/init_64.c +2 -18
@@ -799,13 +799,10 @@ void mark_rodata_ro(void)#endif +#ifndef CONFIG_NO_BOOTMEM int __init reserve_bootmem_generic (unsigned long phys,unsigned long len,int flags) { -#ifdef CONFIG_NUMA -int nid, next_nid; -int ret; -#endif unsigned long pfn = phys >>PAGE_SHIFT ;if (pfn >= max_pfn) {
@@ -821,21 +818,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,return -EFAULT ; } -/* Should check here against the e820 map to avoid double free */ -#ifdef CONFIG_NUMA - nid =phys_to_nid (phys); - next_nid =phys_to_nid (phys + len -1 ); -if (nid == next_nid) - ret =reserve_bootmem_node (NODE_DATA (nid), phys, len, flags); -else - ret =reserve_bootmem (phys, len, flags); - -if (ret !=0 ) -return ret; - -#else reserve_bootmem (phys, len, flags); -#endif if (phys+len <=MAX_DMA_PFN *PAGE_SIZE ) { dma_reserve += len /PAGE_SIZE ;
@@ -844,6 +827,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len, return 0; } +#endif int kern_addr_valid (unsigned long addr) {
mm/bootmem.c +6 -0
@@ -526,6 +526,12 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size, }#ifndef CONFIG_NO_BOOTMEM +int __weak __init reserve_bootmem_generic (unsigned long phys,unsigned long len, +int flags) +{ +return reserve_bootmem (phys, len, flags); +} +static unsigned long __init align_idx (struct bootmem_data *bdata,unsigned long idx,unsigned long step) {
Signature · 1 line
1.6.4.2
PATCH 4/17 x86, memblock: Add memblock_x86_to_bootmem()
In reply to Yinghai Lumemblock_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.
--- arch/x86/include/asm/memblock.h | 1 + arch/x86/mm/memblock.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 0 deletions(-)
arch/x86/include/asm/memblock.h +1 -0
@@ -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
arch/x86/mm/memblock.c +28 -0
@@ -86,3 +86,31 @@ 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
Signature · 1 line
1.6.4.2
PATCH 5/17 x86,memblock: Add memblock_x86_reserve_range/memblock_x86_free_range
In reply to Yinghai Luthey are wrappers for core versions.
they are taking start/end/name instead of base/size. will make x86 conversion more easy
could add more debug print out
-v2: change get_max_mapped() to memblock.default_alloc_limit according to Michael
Ellerman and Ben
change to memblock_x86_reserve_range and memblock_x86_free_range according to Michael Ellerman
-v3: call check_and_double after reserve/free, so could avoid to use
find_memblock_area. Suggested by Michael Ellerman
--- arch/x86/include/asm/memblock.h | 3 +++ arch/x86/mm/memblock.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 0 deletions(-)
arch/x86/include/asm/memblock.h +3 -0
@@ -6,4 +6,7 @@u64 memblock_x86_find_in_range_size (u64 start,u64 *sizep,u64 align);void memblock_x86_to_bootmem (u64 start,u64 end); +void memblock_x86_reserve_range (u64 start,u64 end,char *name); +void memblock_x86_free_range (u64 start,u64 end); +#endif
arch/x86/mm/memblock.c +22 -0
@@ -114,3 +114,25 @@ void __init memblock_x86_to_bootmem(u64 start, u64 end) memblock_reserve_reserved_regions(); }#endif + +void __init memblock_x86_reserve_range (u64 start,u64 end,char *name) +{ +if (start == end) +return ; + +if (WARN_ONCE (start > end,"memblock_x86_reserve_range: wrong range [%#llx, %#llx]\n" , start, end)) +return ; + +memblock_reserve (start, end - start); +} + +void __init memblock_x86_free_range (u64 start,u64 end) +{ +if (start == end) +return ; + +if (WARN_ONCE (start > end,"memblock_x86_free_range: wrong range [%#llx, %#llx]\n" , start, end)) +return ; + +memblock_free (start, end - start); +}
Signature · 1 line
1.6.4.2
PATCH 6/17 x86, memblock: Add get_free_all_memory_range()
In reply to Yinghai Luget_free_all_memory_range is for CONFIG_NO_BOOTMEM=y, and will be called by free_all_memory_core_early().
It will use early_node_map aka active ranges subtract memblock.reserved to get all free range, and those ranges will convert to slab pages.
-v4: increase range size
--- arch/x86/include/asm/memblock.h | 2 + arch/x86/mm/memblock.c | 98 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletions(-)
arch/x86/include/asm/memblock.h +2 -0
@@ -8,5 +8,7 @@ void memblock_x86_to_bootmem(u64 start, u64 end);void memblock_x86_reserve_range (u64 start,u64 end,char *name);void memblock_x86_free_range (u64 start,u64 end); +struct range ; +int get_free_all_memory_range (struct range **rangep,int nodeid);#endif
arch/x86/mm/memblock.c +97 -1
104 lines not on this page · raw message
Signature · 1 line
1.6.4.2
PATCH 7/17 x86, memblock: Add memblock_x86_register_active_regions() and memblock_x86_hole_size()
In reply to Yinghai Lumemblock_x86_register_active_regions() will be used to fill early_node_map, the result will be memblock.memory.region AND numa data
memblock_x86_hole_size will be used to find hole size on memblock.memory.region with specified range.
--- arch/x86/include/asm/memblock.h | 4 ++ arch/x86/mm/memblock.c | 67 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 0 deletions(-)
arch/x86/include/asm/memblock.h +4 -0
@@ -11,4 +11,8 @@ void memblock_x86_free_range(u64 start, u64 end);struct range ;int get_free_all_memory_range (struct range **rangep,int nodeid); +void memblock_x86_register_active_regions (int nid,unsigned long start_pfn, +unsigned long last_pfn); +u64 memblock_x86_hole_size (u64 start,u64 end); +#endif
arch/x86/mm/memblock.c +67 -0
70 lines not on this page · raw message
Signature · 1 line
1.6.4.2
PATCH 8/17 memblock: Add find_memory_core_early()
In reply to Yinghai LuAccording to node range in early_node_map[] with __memblock_find_in_range to find free range.
Will be used by memblock_x86_find_in_range_node()
memblock_x86_find_in_range_node will be used to find right buffer for NODE_DATA
--- include/linux/mm.h | 2 ++ mm/page_alloc.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 0 deletions(-)
include/linux/mm.h +2 -0
@@ -1164,6 +1164,8 @@ extern void free_bootmem_with_active_regions(int nid, unsigned long max_low_pfn);int add_from_early_node_map (struct range *range,int az,int nr_range,int nid); +u64 __init find_memory_core_early (int nid,u64 size,u64 align, +u64 goal,u64 limit);void *__alloc_memory_core_early (int nodeid,u64 size,u64 align,u64 goal,u64 limit);typedef int (*work_fn_t )(unsigned long ,unsigned long ,void *);
mm/page_alloc.c +36 -0
@@ -21,6 +21,7 @@#include <linux/pagemap.h> #include <linux/jiffies.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/compiler.h> #include <linux/kernel.h> #include <linux/kmemcheck.h>
@@ -3612,6 +3613,41 @@ void __init free_bootmem_with_active_regions(int nid, } } +#ifdef CONFIG_HAVE_MEMBLOCK +u64 __init find_memory_core_early (int nid,u64 size,u64 align, +u64 goal,u64 limit) +{ +int i; + +/* Need to go over early_node_map to find out good range for node */ +for_each_active_range_index_in_nid (i, nid) { +u64 addr; +u64 ei_start, ei_last; +u64 final_start, final_end; + + ei_last = early_node_map[i].end_pfn; + ei_last <<=PAGE_SHIFT ; + ei_start = early_node_map[i].start_pfn; + ei_start <<=PAGE_SHIFT ; + + final_start =max (ei_start, goal); + final_end =min (ei_last, limit); + +if (final_start >= final_end) +continue ; + + addr =memblock_find_in_range (final_start, final_end, size, align); + +if (addr ==MEMBLOCK_ERROR ) +continue ; + +return addr; + } + +return MEMBLOCK_ERROR ; +} +#endif +int __init add_from_early_node_map (struct range *range,int az,int nr_range,int nid) {
Signature · 1 line
1.6.4.2
PATCH 9/17 x86, memblock: Add memblock_x86_find_in_range_node()
In reply to Yinghai LuIt can be used to find NODE_DATA for numa.
Need to make sure early_node_map[] is filled before it is called, otherwise it will fallback to memblock_find_in_range(), with node range.
--- arch/x86/include/asm/memblock.h | 1 + arch/x86/mm/memblock.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 0 deletions(-)
arch/x86/include/asm/memblock.h +1 -0
@@ -14,5 +14,6 @@ int get_free_all_memory_range(struct range **rangep, int nodeid);void memblock_x86_register_active_regions (int nid,unsigned long start_pfn,unsigned long last_pfn);u64 memblock_x86_hole_size (u64 start,u64 end); +u64 memblock_x86_find_in_range_node (int nid,u64 start,u64 end,u64 size,u64 align);#endif
arch/x86/mm/memblock.c +15 -0
@@ -234,6 +234,21 @@ void __init memblock_x86_free_range(u64 start, u64 end) }/* +* Need to call this function after memblock_x86_register_active_regions, +* so early_node_map[] is filled already. +*/ +u64 __init memblock_x86_find_in_range_node (int nid,u64 start,u64 end,u64 size,u64 align) +{ +u64 addr; + addr =find_memory_core_early (nid, size, align, start, end); +if (addr !=MEMBLOCK_ERROR ) +return addr; + +/* Fallback, should already have start end within node range */ +return memblock_find_in_range (start, end, size, align); +} + +/* * Finds an active region in the address range from start_pfn to last_pfn and * returns its range in ei_startpfn and ei_endpfn for the memblock entry. */
Signature · 1 line
1.6.4.2
PATCH 10/17 x86, memblock: Add memblock_x86_free_memory_in_range()
In reply to Yinghai LuIt will return free memory size in specified range.
We can not use memory_size - reserved_size here, because some reserved area may not be in the scope of memblock.memory.region.
Use memblock.memory.region subtracting memblock.reserved.region to get free range array. then count size of all free ranges.
-v2: Ben insist on using _in_range
--- arch/x86/include/asm/memblock.h | 1 + arch/x86/mm/memblock.c | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 0 deletions(-)
arch/x86/include/asm/memblock.h +1 -0
@@ -15,5 +15,6 @@ void memblock_x86_register_active_regions(int nid, unsigned long start_pfn, unsigned long last_pfn);u64 memblock_x86_hole_size (u64 start,u64 end);u64 memblock_x86_find_in_range_node (int nid,u64 start,u64 end,u64 size,u64 align); +u64 memblock_x86_free_memory_in_range (u64 addr,u64 limit);#endif
arch/x86/mm/memblock.c +48 -0
54 lines not on this page · raw message
Signature · 1 line
1.6.4.2
PATCH 11/17 x86, memblock: Add memblock_x86_memory_in_range()
In reply to Yinghai LuIt will return memory size in specified range according to memblock.memory.region
Try to share some code with memblock_x86_free_memory_in_range() by passing get_free to __memblock_x86_memory_in_range().
-v2: Ben want _in_range in the name instead of size
--- arch/x86/include/asm/memblock.h | 1 + arch/x86/mm/memblock.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletions(-)
arch/x86/include/asm/memblock.h +1 -0
@@ -16,5 +16,6 @@ void memblock_x86_register_active_regions(int nid, unsigned long start_pfn,u64 memblock_x86_hole_size (u64 start,u64 end);u64 memblock_x86_find_in_range_node (int nid,u64 start,u64 end,u64 size,u64 align);u64 memblock_x86_free_memory_in_range (u64 addr,u64 limit); +u64 memblock_x86_memory_in_range (u64 addr,u64 limit);#endif
arch/x86/mm/memblock.c +17 -1
@@ -211,7 +211,7 @@ void __init memblock_x86_to_bootmem(u64 start, u64 end) }#endif -u64 __init memblock_x86_free_memory_in_range (u64 addr,u64 limit) +static u64 __init __memblock_x86_memory_in_range (u64 addr,u64 limit,bool get_free) {int i, count;struct range *range;
@@ -240,6 +240,10 @@ u64 __init memblock_x86_free_memory_in_range(u64 addr, u64 limit) }subtract_range (range, count,0 , addr);subtract_range (range, count, limit,-1ULL ); + +/* Subtract memblock.reserved.region in range ? */ +if (!get_free) + goto sort_and_count_them;for_each_memblock (reserved, r) { final_start =PFN_DOWN (r->base); final_end =PFN_UP (r->base + r->size);
@@ -250,6 +254,8 @@ u64 __init memblock_x86_free_memory_in_range(u64 addr, u64 limit)subtract_range (range, count, final_start, final_end); } + +sort_and_count_them: nr_range =clean_sort_range (range, count); free_size =0 ;
@@ -259,6 +265,16 @@ u64 __init memblock_x86_free_memory_in_range(u64 addr, u64 limit)return free_size <<PAGE_SHIFT ; } +u64 __init memblock_x86_free_memory_in_range (u64 addr,u64 limit) +{ +return __memblock_x86_memory_in_range (addr, limit, true); +} + +u64 __init memblock_x86_memory_in_range (u64 addr,u64 limit) +{ +return __memblock_x86_memory_in_range (addr, limit, false); +} +void __init memblock_x86_reserve_range (u64 start,u64 end,char *name) {if (start == end)
Signature · 1 line
1.6.4.2
PATCH 12/17 x86, memblock: Use memblock_debug to control debug message print out
In reply to Yinghai LuAlso let memblock_x86_reserve_range/memblock_x86_free_range could print out name if memblock=debug is specified
will also print ther name when reserve_memblock_area/free_memblock_area are called.
-v2: according to Ingo, put " if (memblock_debug) " in one place
--- arch/x86/mm/memblock.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-)
arch/x86/mm/memblock.c +12 -8
@@ -118,10 +118,10 @@ static void __init memblock_x86_subtract_reserved(struct range *range, int az)/* Take out region array itself at first*/ memblock_free_reserved_regions (); -pr_info ("Subtract (%ld early reservations)\n" , memblock.reserved.cnt); +memblock_dbg ("Subtract (%ld early reservations)\n" , memblock.reserved.cnt);for_each_memblock (reserved, r) { -pr_info (" [%010llx-%010llx]\n" , (u64 )r->base, (u64 )r->base + r->size -1 ); +memblock_dbg (" [%010llx-%010llx]\n" , (u64 )r->base, (u64 )r->base + r->size -1 ); final_start =PFN_DOWN (r->base); final_end =PFN_UP (r->base + r->size);if (final_start >= final_end)
@@ -193,16 +193,16 @@ void __init memblock_x86_to_bootmem(u64 start, u64 end)memblock_free_reserved_regions (); count = memblock.reserved.cnt; -pr_info ("(%d early reservations) ==> bootmem [%010llx-%010llx]\n" , count, start, end -1 ); +memblock_dbg ("(%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 ); +memblock_dbg (" [%#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" ); +memblock_dbg ("\n" );continue ; } -pr_cont (" ==> [%010llx-%010llx]\n" , final_start, final_end -1 ); +memblock_dbg (" ==> [%#010llx-%#010llx]\n" , final_start, final_end -1 );reserve_bootmem_generic (final_start, final_end - final_start,BOOTMEM_DEFAULT ); }
@@ -280,9 +280,11 @@ void __init memblock_x86_reserve_range(u64 start, u64 end, char *name)if (start == end)return ; -if (WARN_ONCE (start > end,"memblock_x86_reserve_range: wrong range [%#llx, %#llx]\n" , start, end)) +if (WARN_ONCE (start > end,"memblock_x86_reserve_range: wrong range [%#llx, %#llx)\n" , start, end))return ; +memblock_dbg (" memblock_x86_reserve_range: [%#010llx-%#010llx] %16s\n" , start, end -1 , name); +memblock_reserve (start, end - start); }
@@ -291,9 +293,11 @@ void __init memblock_x86_free_range(u64 start, u64 end)if (start == end)return ; -if (WARN_ONCE (start > end,"memblock_x86_free_range: wrong range [%#llx, %#llx]\n" , start, end)) +if (WARN_ONCE (start > end,"memblock_x86_free_range: wrong range [%#llx, %#llx)\n" , start, end))return ; +memblock_dbg (" memblock_x86_free_range: [%#010llx-%#010llx]\n" , start, end -1 ); +memblock_free (start, end - start); }
Signature · 1 line
1.6.4.2
PATCH 13/17 x86: Use memblock to replace early_res
In reply to Yinghai Lu1. 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
--- arch/x86/Kconfig | 9 +-- arch/x86/include/asm/e820.h | 14 ++-- arch/x86/kernel/check.c | 16 ++-- arch/x86/kernel/e820.c | 159 +++++++++++++-------------------------- arch/x86/kernel/head.c | 3 +- arch/x86/kernel/head32.c | 6 +- arch/x86/kernel/head64.c | 3 + arch/x86/kernel/mpparse.c | 5 +- arch/x86/kernel/setup.c | 46 ++++++++--- arch/x86/kernel/setup_percpu.c | 6 -- arch/x86/mm/numa_64.c | 9 +- mm/bootmem.c | 3 + mm/page_alloc.c | 50 ++++--------- mm/sparse-vmemmap.c | 11 --- 14 files changed, 141 insertions(+), 199 deletions(-)
arch/x86/Kconfig +3 -6
@@ -27,6 +27,7 @@ config X86 select HAVE_PERF_EVENTS if (!M386 && !M486) select HAVE_IOREMAP_PROT select HAVE_KPROBES + select HAVE_MEMBLOCK select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_FRAME_POINTERS select HAVE_DMA_ATTRS
@@ -193,9 +194,6 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING config ARCH_SUPPORTS_DEBUG_PAGEALLOC def_bool y -config HAVE_EARLY_RES - def_bool y - config HAVE_INTEL_TXT def_bool y depends on EXPERIMENTAL && DMAR && ACPI
@@ -588,14 +586,13 @@ config NO_BOOTMEM default y bool "Disable Bootmem code" ---help--- - Use early_res directly instead of bootmem before slab is ready. + Use memblock directly instead of bootmem before slab is ready. - allocator (buddy) [generic] - early allocator (bootmem) [generic] - - very early allocator (reserve_early*()) [x86] + - very early allocator (memblock) [some generic] - very very early allocator (early brk model) [x86] So reduce one layer between early allocator to final allocator - config MEMTEST bool "Memtest" ---help---
arch/x86/include/asm/e820.h +8 -6
@@ -117,24 +117,26 @@ extern unsigned long end_user_pfn;extern u64 find_e820_area (u64 start,u64 end,u64 size,u64 align);extern u64 find_e820_area_size (u64 start,u64 *sizep,u64 align);extern u64 early_reserve_e820 (u64 startt,u64 sizet,u64 align); -#include <linux/early_res.h> extern unsigned long e820_end_of_ram_pfn (void );extern unsigned long e820_end_of_low_ram_pfn (void ); -extern int e820_find_active_region (const struct e820entry *ei, -unsigned long start_pfn, -unsigned long last_pfn, -unsigned long *ei_startpfn, -unsigned long *ei_endpfn);extern void e820_register_active_regions (int nid,unsigned long start_pfn,unsigned long end_pfn);extern u64 e820_hole_size (u64 start,u64 end); + +extern u64 early_reserve_e820 (u64 startt,u64 sizet,u64 align); + +void memblock_x86_fill (void ); +extern void finish_e820_parsing (void );extern void e820_reserve_resources (void );extern void e820_reserve_resources_late (void );extern void setup_memory_map (void );extern char *default_machine_specific_memory_setup (void ); +void reserve_early (u64 start,u64 end,char *name); +void free_early (u64 start,u64 end); +/* * Returns true iff the specified range [s,e) is completely contained inside * the ISA region.
arch/x86/kernel/check.c +9 -7
@@ -2,7 +2,8 @@#include <linux/sched.h> #include <linux/kthread.h> #include <linux/workqueue.h> -#include <asm/e820.h> +#include <linux/memblock.h> +#include <asm/proto.h> /*
@@ -18,10 +19,12 @@ static int __read_mostly memory_corruption_check = -1;static unsigned __read_mostly corruption_check_size =64 *1024 ;static unsigned __read_mostly corruption_check_period =60 ;/* seconds */ -static struct e820entry scan_areas[MAX_SCAN_AREAS ]; +static struct scan_area { +u64 addr; +u64 size; +} scan_areas[MAX_SCAN_AREAS ];static int num_scan_areas; -static __init int set_corruption_check (char *arg) {char *end;
@@ -81,9 +84,9 @@ void __init setup_bios_corruption_check(void)while (addr < corruption_check_size && num_scan_areas <MAX_SCAN_AREAS ) {u64 size; - addr =find_e820_area_size (addr, &size,PAGE_SIZE ); + addr =memblock_x86_find_in_range_size (addr, &size,PAGE_SIZE ); -if (!(addr +1 )) +if (addr ==MEMBLOCK_ERROR )break ;if (addr >= corruption_check_size)
@@ -92,7 +95,7 @@ void __init setup_bios_corruption_check(void)if ((addr + size) > corruption_check_size) size = corruption_check_size - addr; -e820_update_range (addr, size,E820_RAM ,E820_RESERVED ); +memblock_x86_reserve_range (addr, addr + size,"SCAN RAM" ); scan_areas[num_scan_areas].addr = addr; scan_areas[num_scan_areas].size = size; num_scan_areas++;
@@ -105,7 +108,6 @@ void __init setup_bios_corruption_check(void)printk (KERN_INFO "Scanning %d areas for low memory corruption\n" , num_scan_areas); -update_e820 (); }
arch/x86/kernel/e820.c +53 -106
219 lines not on this page · raw message
arch/x86/kernel/head.c +2 -1
@@ -1,5 +1,6 @@#include <linux/kernel.h> #include <linux/init.h> +#include <linux/memblock.h> #include <asm/setup.h> #include <asm/bios_ebda.h>
@@ -51,5 +52,5 @@ void __init reserve_ebda_region(void) lowmem =0x9f000 ;/* reserve all memory between lowmem and the 1MB mark */ -reserve_early_overlap_ok (lowmem,0x100000 ,"BIOS reserved" ); +memblock_x86_reserve_range (lowmem,0x100000 ,"* BIOS reserved" ); }
arch/x86/kernel/head32.c +4 -2
@@ -8,6 +8,7 @@#include <linux/init.h> #include <linux/start_kernel.h> #include <linux/mm.h> +#include <linux/memblock.h> #include <asm/setup.h> #include <asm/sections.h>
@@ -30,14 +31,15 @@ static void __init i386_default_early_setup(void)void __init i386_start_kernel (void ) { +memblock_init (); +#ifdef CONFIG_X86_TRAMPOLINE /* * But first pinch a few for the stack/trampoline stuff * FIXME: Don't need the extra page at 4K, but need to fix * trampoline before removing it. (see the GDT stuff) */ -reserve_early_overlap_ok (PAGE_SIZE ,PAGE_SIZE +PAGE_SIZE , -"EX TRAMPOLINE" ); +memblock_x86_reserve_range (PAGE_SIZE ,PAGE_SIZE +PAGE_SIZE ,"EX TRAMPOLINE" );#endif reserve_early (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" );
arch/x86/kernel/head64.c +3 -0
@@ -12,6 +12,7 @@#include <linux/percpu.h> #include <linux/start_kernel.h> #include <linux/io.h> +#include <linux/memblock.h> #include <asm/processor.h> #include <asm/proto.h>
@@ -96,6 +97,8 @@ void __init x86_64_start_kernel(char * real_mode_data)void __init x86_64_start_reservations (char *real_mode_data) { +memblock_init (); +copy_bootdata (__va (real_mode_data));reserve_early (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" );
arch/x86/kernel/mpparse.c +3 -2
@@ -11,6 +11,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/kernel_stat.h> #include <linux/mc146818rtc.h> #include <linux/bitops.h>
@@ -641,7 +642,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf) {unsigned long size =get_mpc_size (mpf->physptr); -reserve_early_overlap_ok (mpf->physptr, mpf->physptr+size,"MP-table mpc" ); +memblock_x86_reserve_range (mpf->physptr, mpf->physptr+size,"* MP-table mpc" ); }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) mpf, (u64)virt_to_phys(mpf)); mem =virt_to_phys (mpf); -reserve_early_overlap_ok (mem, mem +sizeof (*mpf),"MP-table mpf" ); +memblock_x86_reserve_range (mem, mem +sizeof (*mpf),"* MP-table mpf" );if (mpf->physptr)smp_reserve_memory (mpf);
arch/x86/kernel/setup.c +33 -13
94 lines not on this page · raw message
arch/x86/kernel/setup_percpu.c +0 -6
@@ -131,13 +131,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)static void __init pcpu_fc_free (void *ptr,size_t size) { -#ifdef CONFIG_NO_BOOTMEM -u64 start =__pa (ptr); -u64 end = start + size; -free_early_partial (start, end); -#else free_bootmem (__pa (ptr), size); -#endif }static int __init pcpu_cpu_distance (unsigned int from,unsigned int to)
arch/x86/mm/numa_64.c +5 -4
@@ -7,6 +7,7 @@#include <linux/string.h> #include <linux/init.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/mmzone.h> #include <linux/ctype.h> #include <linux/module.h>
@@ -171,8 +172,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,if (start < (MAX_DMA32_PFN <<PAGE_SHIFT ) && end > (MAX_DMA32_PFN <<PAGE_SHIFT )) start =MAX_DMA32_PFN <<PAGE_SHIFT ; - mem =find_e820_area (start, end, size, align); -if (mem !=-1L ) + mem =memblock_x86_find_in_range_node (nodeid, start, end, size, align); +if (mem !=MEMBLOCK_ERROR )return __va (mem);/* extend the search scope */
@@ -181,8 +182,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start, start =MAX_DMA32_PFN <<PAGE_SHIFT ; else start =MAX_DMA_PFN <<PAGE_SHIFT ; - mem =find_e820_area (start, end, size, align); -if (mem !=-1L ) + mem =memblock_x86_find_in_range_node (nodeid, start, end, size, align); +if (mem !=MEMBLOCK_ERROR )return __va (mem); printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
mm/bootmem.c +3 -0
@@ -15,6 +15,7 @@#include <linux/module.h> #include <linux/kmemleak.h> #include <linux/range.h> +#include <linux/memblock.h> #include <asm/bug.h> #include <asm/io.h>
@@ -434,6 +435,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, unsigned long size) {#ifdef CONFIG_NO_BOOTMEM +kmemleak_free_part (__va (physaddr), size);free_early (physaddr, physaddr + size);#else unsigned long start, end;
@@ -459,6 +461,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,void __init free_bootmem (unsigned long addr,unsigned long size) {#ifdef CONFIG_NO_BOOTMEM +kmemleak_free_part (__va (addr), size);free_early (addr, addr + size);#else unsigned long start, end;
mm/page_alloc.c +15 -35
61 lines not on this page · raw message
mm/sparse-vmemmap.c +0 -11
@@ -220,18 +220,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,if (vmemmap_buf_start) {/* need to free left buf */ -#ifdef CONFIG_NO_BOOTMEM -free_early (__pa (vmemmap_buf_start),__pa (vmemmap_buf_end)); -if (vmemmap_buf_start < vmemmap_buf) { -char name[15 ]; - -snprintf (name,sizeof (name),"MEMMAP %d" , nodeid); -reserve_early_without_check (__pa (vmemmap_buf_start), -__pa (vmemmap_buf), name); - } -#else free_bootmem (__pa (vmemmap_buf), vmemmap_buf_end - vmemmap_buf); -#endif vmemmap_buf =NULL ; vmemmap_buf_end =NULL ; }
Signature · 1 line
1.6.4.2
PATCH 14/17 x86: Replace e820_/_early string with memblock_
In reply to Yinghai Lu1.include linux/memblock.h directly. so later could reduce e820.h reference. 2 this patch is done by sed scripts mainly
-v2: use MEMBLOCK_ERROR instead of -1ULL or -1UL
--- arch/x86/include/asm/efi.h | 2 +- arch/x86/kernel/acpi/sleep.c | 9 +++++---- arch/x86/kernel/apic/numaq_32.c | 3 ++- arch/x86/kernel/efi.c | 5 +++-- arch/x86/kernel/head32.c | 4 ++-- arch/x86/kernel/head64.c | 4 ++-- arch/x86/kernel/setup.c | 29 ++++++++++++++--------------- arch/x86/kernel/trampoline.c | 10 +++++----- arch/x86/mm/init.c | 10 ++++++---- arch/x86/mm/init_32.c | 14 ++++++++------ arch/x86/mm/init_64.c | 11 ++++++----- arch/x86/mm/k8topology_64.c | 4 +++- arch/x86/mm/memtest.c | 7 +++---- arch/x86/mm/numa_32.c | 25 +++++++++++++------------ arch/x86/mm/numa_64.c | 34 +++++++++++++++++----------------- arch/x86/mm/srat_32.c | 3 ++- arch/x86/mm/srat_64.c | 11 ++++++----- arch/x86/xen/mmu.c | 5 +++-- arch/x86/xen/setup.c | 3 ++- mm/bootmem.c | 4 ++-- 20 files changed, 105 insertions(+), 92 deletions(-)
arch/x86/include/asm/efi.h +1 -1
@@ -90,7 +90,7 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,#endif /* CONFIG_X86_32 */ extern int add_efi_memmap; -extern void efi_reserve_early (void ); +extern void efi_memblock_x86_reserve_range (void );extern void efi_call_phys_prelog (void );extern void efi_call_phys_epilog (void );
arch/x86/kernel/acpi/sleep.c +5 -4
@@ -7,6 +7,7 @@#include <linux/acpi.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/dmi.h> #include <linux/cpumask.h> #include <asm/segment.h>
@@ -125,7 +126,7 @@ void acpi_restore_state_mem(void)*/ void __init acpi_reserve_wakeup_memory (void ) { -unsigned long mem; +phys_addr_t mem;if ((&wakeup_code_end - &wakeup_code_start) >WAKEUP_SIZE ) { printk(KERN_ERR
@@ -133,15 +134,15 @@ void __init acpi_reserve_wakeup_memory(void)return ; } - mem =find_e820_area (0 ,1 <<20 ,WAKEUP_SIZE ,PAGE_SIZE ); + mem =memblock_find_in_range (0 ,1 <<20 ,WAKEUP_SIZE ,PAGE_SIZE ); -if (mem ==-1L ) { +if (mem ==MEMBLOCK_ERROR ) {printk (KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n" );return ; } acpi_realmode = (unsigned long )phys_to_virt (mem); acpi_wakeup_address = mem; -reserve_early (mem, mem +WAKEUP_SIZE ,"ACPI WAKEUP" ); +memblock_x86_reserve_range (mem, mem +WAKEUP_SIZE ,"ACPI WAKEUP" ); }
arch/x86/kernel/apic/numaq_32.c +2 -1
@@ -26,6 +26,7 @@#include <linux/nodemask.h> #include <linux/topology.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/threads.h> #include <linux/cpumask.h> #include <linux/kernel.h>
@@ -88,7 +89,7 @@ static inline void numaq_register_node(int node, struct sys_cfg_data *scd) node_end_pfn[node] =MB_TO_PAGES (eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); -e820_register_active_regions (node, node_start_pfn[node], +memblock_x86_register_active_regions (node, node_start_pfn[node], node_end_pfn[node]);memory_present (node, node_start_pfn[node], node_end_pfn[node]);
arch/x86/kernel/efi.c +3 -2
@@ -30,6 +30,7 @@#include <linux/init.h> #include <linux/efi.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/spinlock.h> #include <linux/uaccess.h> #include <linux/time.h>
@@ -275,7 +276,7 @@ static void __init do_add_efi_memmap(void)sanitize_e820_map (e820.map,ARRAY_SIZE (e820.map), &e820.nr_map); } -void __init efi_reserve_early (void ) +void __init efi_memblock_x86_reserve_range (void ) {unsigned long pmap;
@@ -290,7 +291,7 @@ void __init efi_reserve_early(void) boot_params.efi_info.efi_memdesc_size; memmap.desc_version = boot_params.efi_info.efi_memdesc_version; memmap.desc_size = boot_params.efi_info.efi_memdesc_size; -reserve_early (pmap, pmap + memmap.nr_map * memmap.desc_size, +memblock_x86_reserve_range (pmap, pmap + memmap.nr_map * memmap.desc_size,"EFI memmap" ); }
arch/x86/kernel/head32.c +2 -2
@@ -42,7 +42,7 @@ void __init i386_start_kernel(void)memblock_x86_reserve_range (PAGE_SIZE ,PAGE_SIZE +PAGE_SIZE ,"EX TRAMPOLINE" );#endif -reserve_early (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" ); +memblock_x86_reserve_range (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" );#ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */
@@ -51,7 +51,7 @@ void __init i386_start_kernel(void)u64 ramdisk_image = boot_params.hdr.ramdisk_image;u64 ramdisk_size = boot_params.hdr.ramdisk_size;u64 ramdisk_end =PAGE_ALIGN (ramdisk_image + ramdisk_size); - reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); + memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK"); }#endif
arch/x86/kernel/head64.c +2 -2
@@ -101,7 +101,7 @@ void __init x86_64_start_reservations(char *real_mode_data)copy_bootdata (__va (real_mode_data)); -reserve_early (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" ); +memblock_x86_reserve_range (__pa_symbol (&_text),__pa_symbol (&__bss_stop),"TEXT DATA BSS" );#ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */
@@ -110,7 +110,7 @@ void __init x86_64_start_reservations(char *real_mode_data)unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;unsigned long ramdisk_end =PAGE_ALIGN (ramdisk_image + ramdisk_size); - reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); + memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK"); }#endif
arch/x86/kernel/setup.c +14 -15
@@ -303,7 +303,7 @@ static inline void init_gbpages(void)static void __init reserve_brk (void ) {if (_brk_end > _brk_start) -reserve_early (__pa (_brk_start),__pa (_brk_end),"BRK" ); +memblock_x86_reserve_range (__pa (_brk_start),__pa (_brk_end),"BRK" );/* Mark brk area as locked down and no longer taking any new allocations */
@@ -325,17 +325,16 @@ static void __init relocate_initrd(void)char *p, *q;/* We need to move the initrd down into lowmem */ - ramdisk_here =find_e820_area (0 , end_of_lowmem, area_size, + ramdisk_here =memblock_find_in_range (0 , end_of_lowmem, area_size,PAGE_SIZE ); -if (ramdisk_here ==-1ULL ) +if (ramdisk_here ==MEMBLOCK_ERROR )panic ("Cannot find place for new RAMDISK of size %lld\n" , ramdisk_size);/* Note: this includes all the lowmem currently occupied by the initrd, we rely on that fact to keep the data intact. */ -reserve_early (ramdisk_here, ramdisk_here + area_size, -"NEW RAMDISK" ); +memblock_x86_reserve_range (ramdisk_here, ramdisk_here + area_size,"NEW RAMDISK" ); initrd_start = ramdisk_here +PAGE_OFFSET ; initrd_end = initrd_start + ramdisk_size; printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n",
@@ -391,7 +390,7 @@ static void __init reserve_initrd(void) initrd_start =0 ;if (ramdisk_size >= (end_of_lowmem>>1 )) { -free_early (ramdisk_image, ramdisk_end); +memblock_x86_free_range (ramdisk_image, ramdisk_end);printk (KERN_ERR "initrd too large to handle, " "disabling initrd\n" );return ;
@@ -414,7 +413,7 @@ static void __init reserve_initrd(void)relocate_initrd (); - free_early(ramdisk_image, ramdisk_end); + memblock_x86_free_range(ramdisk_image, ramdisk_end); }#else static void __init reserve_initrd (void )
@@ -470,7 +469,7 @@ static void __init e820_reserve_setup_data(void)e820_print_map ("reserve setup_data" ); } -static void __init reserve_early_setup_data (void ) +static void __init memblock_x86_reserve_range_setup_data (void ) {struct setup_data *data;u64 pa_data;
@@ -482,7 +481,7 @@ static void __init reserve_early_setup_data(void)while (pa_data) { data =early_memremap (pa_data,sizeof (*data));sprintf (buf,"setup data %x" , data->type); -reserve_early (pa_data, pa_data+sizeof (*data)+data->len, buf); +memblock_x86_reserve_range (pa_data, pa_data+sizeof (*data)+data->len, buf); pa_data = data->next;early_iounmap (data,sizeof (*data)); }
@@ -520,23 +519,23 @@ static void __init reserve_crashkernel(void)if (crash_base <=0 ) {const unsigned long long alignment =16 <<20 ;/* 16M */ - crash_base =find_e820_area (alignment,ULONG_MAX , crash_size, + crash_base =memblock_find_in_range (alignment,ULONG_MAX , crash_size, alignment); -if (crash_base ==-1ULL ) { +if (crash_base ==MEMBLOCK_ERROR ) {pr_info ("crashkernel reservation failed - No suitable area found.\n" );return ; } }else {unsigned long long start; - start =find_e820_area (crash_base,ULONG_MAX , crash_size, + start =memblock_find_in_range (crash_base,ULONG_MAX , crash_size,1 <<20 );if (start != crash_base) {pr_info ("crashkernel reservation failed - memory is in use.\n" );return ; } } -reserve_early (crash_base, crash_base + crash_size,"CRASH KERNEL" ); +memblock_x86_reserve_range (crash_base, crash_base + crash_size,"CRASH KERNEL" ); printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " "for crashkernel (System RAM: %ldMB)\n",
@@ -792,7 +791,7 @@ void __init setup_arch(char **cmdline_p)#endif 4)) { efi_enabled =1 ; -efi_reserve_early (); +efi_memblock_x86_reserve_range (); }#endif
@@ -852,7 +851,7 @@ void __init setup_arch(char **cmdline_p)vmi_activate ();/* after early param, so could get panic from serial */ -reserve_early_setup_data (); +memblock_x86_reserve_range_setup_data ();if (acpi_mps_check ()) {#ifdef CONFIG_X86_LOCAL_APIC
arch/x86/kernel/trampoline.c +5 -5
@@ -1,7 +1,7 @@#include <linux/io.h> +#include <linux/memblock.h> #include <asm/trampoline.h> -#include <asm/e820.h> #if defined(CONFIG_X86_64 ) && defined(CONFIG_ACPI_SLEEP )#define __trampinit
@@ -16,15 +16,15 @@ unsigned char *__trampinitdata trampoline_base;void __init reserve_trampoline_memory (void ) { -unsigned long mem; +phys_addr_t mem;/* Has to be in very low memory so we can execute real-mode AP code. */ - mem =find_e820_area (0 ,1 <<20 ,TRAMPOLINE_SIZE ,PAGE_SIZE ); -if (mem ==-1L ) + mem =memblock_find_in_range (0 ,1 <<20 ,TRAMPOLINE_SIZE ,PAGE_SIZE ); +if (mem ==MEMBLOCK_ERROR )panic ("Cannot allocate trampoline\n" ); trampoline_base =__va (mem); -reserve_early (mem, mem +TRAMPOLINE_SIZE ,"TRAMPOLINE" ); +memblock_x86_reserve_range (mem, mem +TRAMPOLINE_SIZE ,"TRAMPOLINE" ); }/*
arch/x86/mm/init.c +6 -4
@@ -2,6 +2,7 @@#include <linux/initrd.h> #include <linux/ioport.h> #include <linux/swap.h> +#include <linux/memblock.h> #include <asm/cacheflush.h> #include <asm/e820.h>
@@ -33,6 +34,7 @@ static void __init find_early_table_space(unsigned long end, int use_pse, int use_gbpages) {unsigned long puds, pmds, ptes, tables, start; +phys_addr_t base; puds = (end +PUD_SIZE -1 ) >>PUD_SHIFT ; tables =roundup (puds *sizeof (pud_t),PAGE_SIZE );
@@ -75,12 +77,12 @@ static void __init find_early_table_space(unsigned long end, int use_pse,#else start =0x8000 ;#endif - e820_table_start =find_e820_area (start, max_pfn_mapped<<PAGE_SHIFT , + base =memblock_find_in_range (start, max_pfn_mapped<<PAGE_SHIFT , tables,PAGE_SIZE ); -if (e820_table_start ==-1UL ) +if (base ==MEMBLOCK_ERROR )panic ("Cannot find space for the kernel page tables" ); - e820_table_start >>=PAGE_SHIFT ; + e820_table_start = base >>PAGE_SHIFT ; e820_table_end = e820_table_start; e820_table_top = e820_table_start + (tables >>PAGE_SHIFT );
@@ -299,7 +301,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,__flush_tlb_all ();if (!after_bootmem && e820_table_end > e820_table_start) -reserve_early (e820_table_start <<PAGE_SHIFT , +memblock_x86_reserve_range (e820_table_start <<PAGE_SHIFT , e820_table_end <<PAGE_SHIFT ,"PGTABLE" );if (!after_bootmem)
arch/x86/mm/init_32.c +8 -6
@@ -25,6 +25,7 @@#include <linux/pfn.h> #include <linux/poison.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/proc_fs.h> #include <linux/memory_hotplug.h> #include <linux/initrd.h>
@@ -712,14 +713,14 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn, highstart_pfn = highend_pfn = max_pfn;if (max_pfn > max_low_pfn) highstart_pfn = max_low_pfn; -e820_register_active_regions (0 ,0 , highend_pfn); +memblock_x86_register_active_regions (0 ,0 , highend_pfn);sparse_memory_present_with_active_regions (0 );printk (KERN_NOTICE "%ldMB HIGHMEM available.\n" ,pages_to_mb (highend_pfn - highstart_pfn)); num_physpages = highend_pfn; high_memory = (void *)__va (highstart_pfn *PAGE_SIZE -1 ) +1 ;#else -e820_register_active_regions (0 ,0 , max_low_pfn); +memblock_x86_register_active_regions (0 ,0 , max_low_pfn);sparse_memory_present_with_active_regions (0 ); num_physpages = max_low_pfn; high_memory = (void *)__va (max_low_pfn *PAGE_SIZE -1 ) +1 ;
@@ -776,16 +777,16 @@ void __init setup_bootmem_allocator(void) {#ifndef CONFIG_NO_BOOTMEM int nodeid; -unsigned long bootmap_size, bootmap; +phys_addr_t bootmap_size, bootmap;/* * Initialize the boot-time allocator (with low memory only): */ bootmap_size =bootmem_bootmap_pages (max_low_pfn)<<PAGE_SHIFT ; - bootmap =find_e820_area (0 , max_pfn_mapped<<PAGE_SHIFT , bootmap_size, + bootmap =memblock_find_in_range (0 , max_pfn_mapped<<PAGE_SHIFT , bootmap_size,PAGE_SIZE ); -if (bootmap ==-1L ) +if (bootmap ==MEMBLOCK_ERROR )panic ("Cannot find bootmem map of size %ld\n" , bootmap_size); -reserve_early (bootmap, bootmap + bootmap_size,"BOOTMAP" ); +memblock_x86_reserve_range (bootmap, bootmap + bootmap_size,"BOOTMAP" );#endif printk(KERN_INFO " mapped low ram: 0 - %08lx\n",
@@ -1069,3 +1070,4 @@ void mark_rodata_ro(void) #endif }#endif +
arch/x86/mm/init_64.c +6 -5
@@ -21,6 +21,7 @@#include <linux/initrd.h> #include <linux/pagemap.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/proc_fs.h> #include <linux/pci.h> #include <linux/pfn.h>
@@ -577,18 +578,18 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,unsigned long bootmap_size, bootmap; bootmap_size =bootmem_bootmap_pages (end_pfn)<<PAGE_SHIFT ; - bootmap =find_e820_area (0 , end_pfn<<PAGE_SHIFT , bootmap_size, + bootmap =memblock_find_in_range (0 , end_pfn<<PAGE_SHIFT , bootmap_size,PAGE_SIZE ); -if (bootmap ==-1L ) +if (bootmap ==MEMBLOCK_ERROR )panic ("Cannot find bootmem map of size %ld\n" , bootmap_size); -reserve_early (bootmap, bootmap + bootmap_size,"BOOTMAP" ); +memblock_x86_reserve_range (bootmap, bootmap + bootmap_size,"BOOTMAP" );/* don't touch min_low_pfn */ bootmap_size =init_bootmem_node (NODE_DATA (0 ), bootmap >>PAGE_SHIFT ,0 , end_pfn); -e820_register_active_regions (0 , start_pfn, end_pfn); +memblock_x86_register_active_regions (0 , start_pfn, end_pfn);free_bootmem_with_active_regions (0 , end_pfn);#else -e820_register_active_regions (0 , start_pfn, end_pfn); +memblock_x86_register_active_regions (0 , start_pfn, end_pfn); #endif }#endif
arch/x86/mm/k8topology_64.c +3 -1
@@ -11,6 +11,8 @@#include <linux/string.h> #include <linux/module.h> #include <linux/nodemask.h> +#include <linux/memblock.h> +#include <asm/io.h> #include <linux/pci_ids.h> #include <linux/acpi.h>
@@ -222,7 +224,7 @@ int __init k8_scan_nodes(void)for_each_node_mask (i, node_possible_map) {int j; -e820_register_active_regions (i, +memblock_x86_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , nodes[i].end >>PAGE_SHIFT );for (j = apicid_base; j < cores + apicid_base; j++)
arch/x86/mm/memtest.c +3 -4
@@ -6,8 +6,7 @@#include <linux/smp.h> #include <linux/init.h> #include <linux/pfn.h> - -#include <asm/e820.h> +#include <linux/memblock.h> static u64 patterns[]__initdata = {0 ,
@@ -35,7 +34,7 @@ static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad) (unsigned long long ) pattern, (unsigned long long ) start_bad, (unsigned long long) end_bad); -reserve_early (start_bad, end_bad,"BAD RAM" ); +memblock_x86_reserve_range (start_bad, end_bad,"BAD RAM" ); }static void __init memtest (u64 pattern,u64 start_phys,u64 size)
@@ -74,7 +73,7 @@ static void __init do_one_pass(u64 pattern, u64 start, u64 end)u64 size =0 ;while (start < end) { - start =find_e820_area_size (start, &size,1 ); + start =memblock_x86_find_in_range_size (start, &size,1 );/* done ? */ if (start >= end)
arch/x86/mm/numa_32.c +13 -12
@@ -24,6 +24,7 @@#include <linux/mm.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/mmzone.h> #include <linux/highmem.h> #include <linux/initrd.h>
@@ -120,7 +121,7 @@ int __init get_memcfg_numa_flat(void) node_start_pfn[0 ] =0 ; node_end_pfn[0 ] = max_pfn; -e820_register_active_regions (0 ,0 , max_pfn); +memblock_x86_register_active_regions (0 ,0 , max_pfn);memory_present (0 ,0 , max_pfn); node_remap_size[0 ] =node_memmap_size_bytes (0 ,0 , max_pfn);
@@ -161,14 +162,14 @@ static void __init allocate_pgdat(int nid)NODE_DATA (nid) = (pg_data_t *)node_remap_start_vaddr[nid]; else {unsigned long pgdat_phys; - pgdat_phys =find_e820_area (min_low_pfn<<PAGE_SHIFT , + pgdat_phys =memblock_find_in_range (min_low_pfn<<PAGE_SHIFT , max_pfn_mapped<<PAGE_SHIFT ,sizeof (pg_data_t),PAGE_SIZE );NODE_DATA (nid) = (pg_data_t *)(pfn_to_kaddr (pgdat_phys>>PAGE_SHIFT ));memset (buf,0 ,sizeof (buf));sprintf (buf,"NODE_DATA %d" , nid); -reserve_early (pgdat_phys, pgdat_phys +sizeof (pg_data_t), buf); +memblock_x86_reserve_range (pgdat_phys, pgdat_phys +sizeof (pg_data_t), buf); }printk (KERN_DEBUG "allocate_pgdat: node %d NODE_DATA %08lx\n" , nid, (unsigned long )NODE_DATA (nid));
@@ -291,15 +292,15 @@ static __init unsigned long calculate_numa_remap_pages(void) PTRS_PER_PTE); node_kva_target <<=PAGE_SHIFT ;do { - node_kva_final =find_e820_area (node_kva_target, + node_kva_final =memblock_find_in_range (node_kva_target, ((u64 )node_end_pfn[nid])<<PAGE_SHIFT , ((u64 )size)<<PAGE_SHIFT ,LARGE_PAGE_BYTES ); node_kva_target -=LARGE_PAGE_BYTES ; - }while (node_kva_final ==-1ULL && + }while (node_kva_final ==MEMBLOCK_ERROR && (node_kva_target>>PAGE_SHIFT ) > (node_start_pfn[nid])); -if (node_kva_final ==-1ULL ) +if (node_kva_final ==MEMBLOCK_ERROR )panic ("Can not get kva ram\n" ); node_remap_size[nid] = size;
@@ -318,9 +319,9 @@ static __init unsigned long calculate_numa_remap_pages(void)* but we could have some hole in high memory, and it will only * check page_is_ram(pfn) && !page_is_reserved_early(pfn) to decide * to use it as free. -* So reserve_early here, hope we don't run out of that array +* So memblock_x86_reserve_range here, hope we don't run out of that array */ -reserve_early (node_kva_final, +memblock_x86_reserve_range (node_kva_final, node_kva_final+(((u64 )size)<<PAGE_SHIFT ),"KVA RAM" );
@@ -367,14 +368,14 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn, kva_target_pfn =round_down (max_low_pfn - kva_pages,PTRS_PER_PTE );do { - kva_start_pfn =find_e820_area (kva_target_pfn<<PAGE_SHIFT , + kva_start_pfn =memblock_find_in_range (kva_target_pfn<<PAGE_SHIFT , max_low_pfn<<PAGE_SHIFT , kva_pages<<PAGE_SHIFT ,PTRS_PER_PTE <<PAGE_SHIFT ) >>PAGE_SHIFT ; kva_target_pfn -=PTRS_PER_PTE ; - }while (kva_start_pfn ==-1UL && kva_target_pfn > min_low_pfn); + }while (kva_start_pfn ==MEMBLOCK_ERROR && kva_target_pfn > min_low_pfn); -if (kva_start_pfn ==-1UL ) +if (kva_start_pfn ==MEMBLOCK_ERROR )panic ("Can not get kva space\n" ); printk(KERN_INFO "kva_start_pfn ~ %lx max_low_pfn ~ %lx\n",
@@ -382,7 +383,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,printk (KERN_INFO "max_pfn = %lx\n" , max_pfn);/* avoid clash with initrd */ -reserve_early (kva_start_pfn<<PAGE_SHIFT , +memblock_x86_reserve_range (kva_start_pfn<<PAGE_SHIFT , (kva_start_pfn + kva_pages)<<PAGE_SHIFT ,"KVA PG" );#ifdef CONFIG_HIGHMEM
arch/x86/mm/numa_64.c +17 -17
@@ -87,16 +87,16 @@ static int __init allocate_cachealigned_memnodemap(void) addr =0x8000 ; nodemap_size =roundup (sizeof (s16) * memnodemapsize,L1_CACHE_BYTES ); - nodemap_addr =find_e820_area (addr, max_pfn<<PAGE_SHIFT , + nodemap_addr =memblock_find_in_range (addr, max_pfn<<PAGE_SHIFT , nodemap_size,L1_CACHE_BYTES ); -if (nodemap_addr ==-1UL ) { +if (nodemap_addr ==MEMBLOCK_ERROR ) {printk (KERN_ERR "NUMA: Unable to allocate Memory to Node hash map\n" ); nodemap_addr = nodemap_size =0 ;return -1 ; } memnodemap =phys_to_virt (nodemap_addr); -reserve_early (nodemap_addr, nodemap_addr + nodemap_size,"MEMNODEMAP" ); +memblock_x86_reserve_range (nodemap_addr, nodemap_addr + nodemap_size,"MEMNODEMAP" );printk (KERN_DEBUG "NUMA: Allocated memnodemap from %lx - %lx\n" , nodemap_addr, nodemap_addr + nodemap_size);
@@ -227,7 +227,7 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)if (node_data[nodeid] ==NULL )return ; nodedata_phys =__pa (node_data[nodeid]); -reserve_early (nodedata_phys, nodedata_phys + pgdat_size,"NODE_DATA" ); +memblock_x86_reserve_range (nodedata_phys, nodedata_phys + pgdat_size,"NODE_DATA" );printk (KERN_INFO " NODE_DATA [%016lx - %016lx]\n" , nodedata_phys, nodedata_phys + pgdat_size -1 ); nid =phys_to_nid (nodedata_phys);
@@ -246,7 +246,7 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)* Find a place for the bootmem map * nodedata_phys could be on other nodes by alloc_bootmem, * so need to sure bootmap_start not to be small, otherwise -* early_node_mem will get that with find_e820_area instead +* early_node_mem will get that with memblock_find_in_range instead * of alloc_bootmem, that could clash with reserved range */ bootmap_pages =bootmem_bootmap_pages (last_pfn - start_pfn);
@@ -258,12 +258,12 @@ setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) bootmap =early_node_mem (nodeid, bootmap_start, end, bootmap_pages<<PAGE_SHIFT ,PAGE_SIZE );if (bootmap ==NULL ) { -free_early (nodedata_phys, nodedata_phys + pgdat_size); +memblock_x86_free_range (nodedata_phys, nodedata_phys + pgdat_size); node_data[nodeid] =NULL ;return ; } bootmap_start =__pa (bootmap); -reserve_early (bootmap_start, bootmap_start+(bootmap_pages<<PAGE_SHIFT ), +memblock_x86_reserve_range (bootmap_start, bootmap_start+(bootmap_pages<<PAGE_SHIFT ),"BOOTMAP" ); bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
@@ -417,7 +417,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr, nr_nodes =MAX_NUMNODES ; } - size = (max_addr - addr -e820_hole_size (addr, max_addr)) / nr_nodes; + size = (max_addr - addr -memblock_x86_hole_size (addr, max_addr)) / nr_nodes;/* * Calculate the number of big nodes that can be allocated as a result * of consolidating the remainder.
@@ -453,7 +453,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,* non-reserved memory is less than the per-node size. */ while (end - physnodes[i].start - -e820_hole_size (physnodes[i].start, end) < size) { +memblock_x86_hole_size (physnodes[i].start, end) < size) { end +=FAKE_NODE_MIN_SIZE ;if (end > physnodes[i].end) { end = physnodes[i].end;
@@ -467,7 +467,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,* this one must extend to the boundary. */ if (end < dma32_end && dma32_end - end - -e820_hole_size (end, dma32_end) <FAKE_NODE_MIN_SIZE ) +memblock_x86_hole_size (end, dma32_end) <FAKE_NODE_MIN_SIZE ) end = dma32_end;/*
@@ -476,7 +476,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,* physical node. */ if (physnodes[i].end - end - -e820_hole_size (end, physnodes[i].end) < size) +memblock_x86_hole_size (end, physnodes[i].end) < size) end = physnodes[i].end;/*
@@ -504,7 +504,7 @@ static u64 __init find_end_of_node(u64 start, u64 max_addr, u64 size) {u64 end = start + size; -while (end - start -e820_hole_size (start, end) < size) { +while (end - start -memblock_x86_hole_size (start, end) < size) { end +=FAKE_NODE_MIN_SIZE ;if (end > max_addr) { end = max_addr;
@@ -533,7 +533,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)* creates a uniform distribution of node sizes across the entire * machine (but not necessarily over physical nodes). */ - min_size = (max_addr - addr -e820_hole_size (addr, max_addr)) / + min_size = (max_addr - addr -memblock_x86_hole_size (addr, max_addr)) /MAX_NUMNODES ; min_size =max (min_size,FAKE_NODE_MIN_SIZE );if ((min_size &FAKE_NODE_MIN_HASH_MASK ) < min_size)
@@ -566,7 +566,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)* this one must extend to the boundary. */ if (end < dma32_end && dma32_end - end - -e820_hole_size (end, dma32_end) <FAKE_NODE_MIN_SIZE ) +memblock_x86_hole_size (end, dma32_end) <FAKE_NODE_MIN_SIZE ) end = dma32_end;/*
@@ -575,7 +575,7 @@ static int __init split_nodes_size_interleave(u64 addr, u64 max_addr, u64 size)* physical node. */ if (physnodes[i].end - end - -e820_hole_size (end, physnodes[i].end) < size) +memblock_x86_hole_size (end, physnodes[i].end) < size) end = physnodes[i].end;/*
@@ -639,7 +639,7 @@ static int __init numa_emulation(unsigned long start_pfn,*/ remove_all_active_ranges ();for_each_node_mask (i, node_possible_map) { -e820_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , +memblock_x86_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , nodes[i].end >>PAGE_SHIFT );setup_node_bootmem (i, nodes[i].start, nodes[i].end); }
@@ -692,7 +692,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,node_set (0 , node_possible_map);for (i =0 ; i < nr_cpu_ids; i++)numa_set_node (i,0 ); -e820_register_active_regions (0 , start_pfn, last_pfn); +memblock_x86_register_active_regions (0 , start_pfn, last_pfn);setup_node_bootmem (0 , start_pfn <<PAGE_SHIFT , last_pfn <<PAGE_SHIFT ); }
arch/x86/mm/srat_32.c +2 -1
@@ -25,6 +25,7 @@*/ #include <linux/mm.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/mmzone.h> #include <linux/acpi.h> #include <linux/nodemask.h>
@@ -264,7 +265,7 @@ int __init get_memcfg_from_srat(void)if (node_read_chunk (chunk->nid, chunk))continue ; -e820_register_active_regions (chunk->nid, chunk->start_pfn, +memblock_x86_register_active_regions (chunk->nid, chunk->start_pfn,min (chunk->end_pfn, max_pfn)); }/* for out of order entries in SRAT */
arch/x86/mm/srat_64.c +6 -5
@@ -16,6 +16,7 @@#include <linux/module.h> #include <linux/topology.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/mm.h> #include <asm/proto.h> #include <asm/numa.h>
@@ -98,15 +99,15 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)unsigned long phys; length = slit->header.length; - phys =find_e820_area (0 , max_pfn_mapped<<PAGE_SHIFT , length, + phys =memblock_find_in_range (0 , max_pfn_mapped<<PAGE_SHIFT , length,PAGE_SIZE ); -if (phys ==-1L ) +if (phys ==MEMBLOCK_ERROR )panic (" Can not save slit!\n" ); acpi_slit =__va (phys);memcpy (acpi_slit, slit, length); -reserve_early (phys, phys + length,"ACPI SLIT" ); +memblock_x86_reserve_range (phys, phys + length,"ACPI SLIT" ); }/* Callback for Proximity Domain -> x2APIC mapping */
@@ -324,7 +325,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) pxmram =0 ; } - e820ram = max_pfn - (e820_hole_size (0 , max_pfn<<PAGE_SHIFT )>>PAGE_SHIFT ); + e820ram = max_pfn - (memblock_x86_hole_size (0 , max_pfn<<PAGE_SHIFT )>>PAGE_SHIFT );/* We seem to lose 3 pages somewhere. Allow 1M of slack. */ if ((long )(e820ram - pxmram) >= (1 <<(20 -PAGE_SHIFT ))) { printk(KERN_ERR
@@ -421,7 +422,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) }for_each_node_mask (i, nodes_parsed) -e820_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , +memblock_x86_register_active_regions (i, nodes[i].start >>PAGE_SHIFT , nodes[i].end >>PAGE_SHIFT );/* for out of order entries in SRAT */ sort_node_map ();
arch/x86/xen/mmu.c +3 -2
@@ -44,6 +44,7 @@#include <linux/bug.h> #include <linux/module.h> #include <linux/gfp.h> +#include <linux/memblock.h> #include <asm/pgtable.h> #include <asm/tlbflush.h>
@@ -1735,7 +1736,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,__xen_write_cr3 (true,__pa (pgd));xen_mc_issue (PARAVIRT_LAZY_CPU ); -reserve_early (__pa (xen_start_info->pt_base), +memblock_x86_reserve_range (__pa (xen_start_info->pt_base),__pa (xen_start_info->pt_base + xen_start_info->nr_pt_frames *PAGE_SIZE ),"XEN PAGETABLES" );
@@ -1773,7 +1774,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,pin_pagetable_pfn (MMUEXT_PIN_L3_TABLE ,PFN_DOWN (__pa (swapper_pg_dir))); -reserve_early (__pa (xen_start_info->pt_base), +memblock_x86_reserve_range (__pa (xen_start_info->pt_base),__pa (xen_start_info->pt_base + xen_start_info->nr_pt_frames *PAGE_SIZE ),"XEN PAGETABLES" );
arch/x86/xen/setup.c +2 -1
@@ -8,6 +8,7 @@#include <linux/sched.h> #include <linux/mm.h> #include <linux/pm.h> +#include <linux/memblock.h> #include <asm/elf.h> #include <asm/vdso.h>
@@ -61,7 +62,7 @@ char * __init xen_memory_setup(void)* - xen_start_info * See comment above "struct start_info" in <xen/interface/xen.h> */ -reserve_early (__pa (xen_start_info->mfn_list), +memblock_x86_reserve_range (__pa (xen_start_info->mfn_list),__pa (xen_start_info->pt_base),"XEN START INFO" );
mm/bootmem.c +2 -2
@@ -436,7 +436,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, {#ifdef CONFIG_NO_BOOTMEM kmemleak_free_part (__va (physaddr), size); -free_early (physaddr, physaddr + size); +memblock_x86_free_range (physaddr, physaddr + size);#else unsigned long start, end;
@@ -462,7 +462,7 @@ void __init free_bootmem(unsigned long addr, unsigned long size) {#ifdef CONFIG_NO_BOOTMEM kmemleak_free_part (__va (addr), size); -free_early (addr, addr + size); +memblock_x86_free_range (addr, addr + size);#else unsigned long start, end;
Signature · 1 line
1.6.4.2
PATCH 15/17 x86: Remove not used early_res code
In reply to Yinghai Luand some functions in e820.c that are not used anymore
--- arch/x86/include/asm/e820.h | 14 - arch/x86/kernel/e820.c | 52 ---- include/linux/early_res.h | 23 -- kernel/Makefile | 1 - kernel/early_res.c | 590 ------------------------------------------- 5 files changed, 0 insertions(+), 680 deletions(-) delete mode 100644 include/linux/early_res.h delete mode 100644 kernel/early_res.c
arch/x86/include/asm/e820.h +0 -14
@@ -112,31 +112,17 @@ static inline void early_memtest(unsigned long start, unsigned long end) }#endif -extern unsigned long end_user_pfn; - -extern u64 find_e820_area (u64 start,u64 end,u64 size,u64 align); -extern u64 find_e820_area_size (u64 start,u64 *sizep,u64 align); -extern u64 early_reserve_e820 (u64 startt,u64 sizet,u64 align); -extern unsigned long e820_end_of_ram_pfn (void );extern unsigned long e820_end_of_low_ram_pfn (void ); -extern void e820_register_active_regions (int nid,unsigned long start_pfn, -unsigned long end_pfn); -extern u64 e820_hole_size (u64 start,u64 end); -extern u64 early_reserve_e820 (u64 startt,u64 sizet,u64 align);void memblock_x86_fill (void ); -extern void finish_e820_parsing (void );extern void e820_reserve_resources (void );extern void e820_reserve_resources_late (void );extern void setup_memory_map (void );extern char *default_machine_specific_memory_setup (void ); -void reserve_early (u64 start,u64 end,char *name); -void free_early (u64 start,u64 end); -/* * Returns true iff the specified range [s,e) is completely contained inside * the ISA region.
arch/x86/kernel/e820.c +0 -52
64 lines not on this page · raw message
include/linux/early_res.h deleted +0 -23
@@ -1,23 +0,0 @@ -#ifndef _LINUX_EARLY_RES_H -#define _LINUX_EARLY_RES_H -#ifdef __KERNEL__ - -extern void reserve_early (u64 start,u64 end,char *name); -extern void reserve_early_overlap_ok (u64 start,u64 end,char *name); -extern void free_early (u64 start,u64 end); -void free_early_partial (u64 start,u64 end); -extern void early_res_to_bootmem (u64 start,u64 end); - -void reserve_early_without_check (u64 start,u64 end,char *name); -u64 find_early_area (u64 ei_start,u64 ei_last,u64 start,u64 end, -u64 size,u64 align); -u64 find_early_area_size (u64 ei_start,u64 ei_last,u64 start, -u64 *sizep,u64 align); -u64 find_fw_memmap_area (u64 start,u64 end,u64 size,u64 align); -u64 get_max_mapped (void ); -#include <linux/range.h> -int get_free_all_memory_range (struct range **rangep,int nodeid); - -#endif /* __KERNEL__ */ - -#endif /* _LINUX_EARLY_RES_H */
kernel/Makefile +0 -1
@@ -11,7 +11,6 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ async.o range.o -obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o obj-y += groups.o ifdef CONFIG_FUNCTION_TRACER
kernel/early_res.c deleted +0 -590
590 lines not on this page · raw message
Signature · 1 line
1.6.4.2
PATCH 16/17 x86, memblock: Use memblock_memory_size()/memblock_free_memory_size() to get correct dma_reserve
In reply to Yinghai Lumemblock_memory_size() will return memory size in memblock.memory.region. memblock_free_memory_size() will return free memory size in memblock.memory.region.
So We can get exact reseved size in specified range.
Set the size right after initmem_init(), because later bootmem API will get area above 16M. (except some fallback).
Later after we remove the bootmem, We could call that just before paging_init().
--- arch/x86/include/asm/e820.h | 2 ++ arch/x86/kernel/e820.c | 17 +++++++++++++++++ arch/x86/kernel/setup.c | 1 + arch/x86/mm/init_64.c | 7 ------- 4 files changed, 20 insertions(+), 7 deletions(-)
arch/x86/include/asm/e820.h +2 -0
@@ -117,6 +117,8 @@ extern unsigned long e820_end_of_low_ram_pfn(void);extern u64 early_reserve_e820 (u64 startt,u64 sizet,u64 align);void memblock_x86_fill (void ); +void memblock_find_dma_reserve (void ); +extern void finish_e820_parsing (void );extern void e820_reserve_resources (void );extern void e820_reserve_resources_late (void );
arch/x86/kernel/e820.c +17 -0
@@ -1105,3 +1105,20 @@ void __init memblock_x86_fill(void)memblock_analyze ();memblock_dump_all (); } + +void __init memblock_find_dma_reserve (void ) +{ +#ifdef CONFIG_X86_64 +u64 free_size_pfn; +u64 mem_size_pfn; +/* +* need to find out used area below MAX_DMA_PFN +* need to use memblock to get free size in [0, MAX_DMA_PFN] +* at first, and assume boot_mem will not take below MAX_DMA_PFN +*/ + mem_size_pfn =memblock_x86_memory_in_range (0 ,MAX_DMA_PFN <<PAGE_SHIFT ) >>PAGE_SHIFT ; + free_size_pfn =memblock_x86_free_memory_in_range (0 ,MAX_DMA_PFN <<PAGE_SHIFT ) >>PAGE_SHIFT ; +set_dma_reserve (mem_size_pfn - free_size_pfn); +#endif +} +
arch/x86/kernel/setup.c +1 -0
@@ -1019,6 +1019,7 @@ void __init setup_arch(char **cmdline_p)#endif initmem_init (0 , max_pfn, acpi, k8); +memblock_find_dma_reserve ();#ifndef CONFIG_NO_BOOTMEM memblock_x86_to_bootmem (0 , max_low_pfn<<PAGE_SHIFT );#endif
arch/x86/mm/init_64.c +0 -7
@@ -53,8 +53,6 @@#include <asm/init.h> #include <linux/bootmem.h> -static unsigned long dma_reserve__initdata ; -static int __init parse_direct_gbpages_off (char *arg) { direct_gbpages =0 ;
@@ -821,11 +819,6 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,reserve_bootmem (phys, len, flags); -if (phys+len <=MAX_DMA_PFN *PAGE_SIZE ) { - dma_reserve += len /PAGE_SIZE ; -set_dma_reserve (dma_reserve); - } - return 0; }#endif
Signature · 1 line
1.6.4.2
PATCH 17/17 x86: remove old bootmem code
In reply to Yinghai LuRequested by Ingo, Thomas and HPA.
it mean 2.6.34 and 2.6.35 have them bootmem and nobootmem for x86. and later for x86 will only have nobootmem
--- arch/x86/Kconfig | 10 +------- arch/x86/kernel/setup.c | 4 --- arch/x86/mm/init_32.c | 56 ----------------------------------------------- arch/x86/mm/init_64.c | 41 ---------------------------------- arch/x86/mm/memblock.c | 29 ------------------------ arch/x86/mm/numa_32.c | 3 -- arch/x86/mm/numa_64.c | 47 --------------------------------------- 7 files changed, 1 insertions(+), 189 deletions(-)
arch/x86/Kconfig +1 -9
@@ -583,15 +583,7 @@ config PARAVIRT_DEBUG a paravirt_op is missing when it is called. config NO_BOOTMEM - default y - bool "Disable Bootmem code" - ---help--- - Use memblock directly instead of bootmem before slab is ready. - - allocator (buddy) [generic] - - early allocator (bootmem) [generic] - - very early allocator (memblock) [some generic] - - very very early allocator (early brk model) [x86] - So reduce one layer between early allocator to final allocator + def_bool y config MEMTEST bool "Memtest"
arch/x86/kernel/setup.c +0 -4
@@ -1020,10 +1020,6 @@ void __init setup_arch(char **cmdline_p)initmem_init (0 , max_pfn, acpi, k8);memblock_find_dma_reserve (); -#ifndef CONFIG_NO_BOOTMEM -memblock_x86_to_bootmem (0 , max_low_pfn<<PAGE_SHIFT ); -#endif -dma32_reserve_bootmem ();#ifdef CONFIG_KVM_CLOCK
arch/x86/mm/init_32.c +0 -56
68 lines not on this page · raw message
arch/x86/mm/init_64.c +0 -41
54 lines not on this page · raw message
arch/x86/mm/memblock.c +0 -29
@@ -109,7 +109,6 @@ static __init struct range *find_range_array(int count)return range; } -#ifdef CONFIG_NO_BOOTMEM static void __init memblock_x86_subtract_reserved (struct range *range,int az) {u64 final_start, final_end;
@@ -182,34 +181,6 @@ int __init get_free_all_memory_range(struct range **rangep, int nodeid) *rangep = range;return nr_range; } -#else -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; -memblock_dbg ("(%d early reservations) ==> bootmem [%#010llx-%#010llx]\n" , count, start, end -1 ); -for_each_memblock (reserved, r) { -memblock_dbg (" [%#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) { -memblock_dbg ("\n" ); -continue ; - } -memblock_dbg (" ==> [%#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 static u64 __init __memblock_x86_memory_in_range (u64 addr,u64 limit,bool get_free) {
arch/x86/mm/numa_32.c +0 -3
@@ -420,9 +420,6 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,for_each_online_node (nid) {memset (NODE_DATA (nid),0 ,sizeof (struct pglist_data ));NODE_DATA (nid)->node_id = nid; -#ifndef CONFIG_NO_BOOTMEM -NODE_DATA (nid)->bdata = &bootmem_node_data[nid]; -#endif }setup_bootmem_allocator ();
arch/x86/mm/numa_64.c +0 -47
66 lines not on this page · raw message
Signature · 1 line
1.6.4.2