diff options
| author | Yinghai Lu <yinghai@kernel.org> | 2010-08-25 16:39:16 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2010-08-27 14:10:54 -0400 |
| commit | edbe7d23b4482e7f33179290bcff3b1feae1c5f3 (patch) | |
| tree | 2bf55fc2cb94e32fdd79018e9e04b55cbe8d49d9 | |
| parent | 88ba088c18457caaf8d2e5f8d36becc731a3d4f6 (diff) | |
memblock: Add find_memory_core_early()
According 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
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
| -rw-r--r-- | include/linux/mm.h | 2 | ||||
| -rw-r--r-- | mm/page_alloc.c | 36 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index a2b48041b910..993e85f0afcb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -1164,6 +1164,8 @@ extern void free_bootmem_with_active_regions(int nid, | |||
| 1164 | unsigned long max_low_pfn); | 1164 | unsigned long max_low_pfn); |
| 1165 | int add_from_early_node_map(struct range *range, int az, | 1165 | int add_from_early_node_map(struct range *range, int az, |
| 1166 | int nr_range, int nid); | 1166 | int nr_range, int nid); |
| 1167 | u64 __init find_memory_core_early(int nid, u64 size, u64 align, | ||
| 1168 | u64 goal, u64 limit); | ||
| 1167 | void *__alloc_memory_core_early(int nodeid, u64 size, u64 align, | 1169 | void *__alloc_memory_core_early(int nodeid, u64 size, u64 align, |
| 1168 | u64 goal, u64 limit); | 1170 | u64 goal, u64 limit); |
| 1169 | typedef int (*work_fn_t)(unsigned long, unsigned long, void *); | 1171 | typedef int (*work_fn_t)(unsigned long, unsigned long, void *); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9bd339eb04c6..8c9b34674d83 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
| 22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
| 23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
| 24 | #include <linux/memblock.h> | ||
| 24 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
| 25 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 26 | #include <linux/kmemcheck.h> | 27 | #include <linux/kmemcheck.h> |
| @@ -3612,6 +3613,41 @@ void __init free_bootmem_with_active_regions(int nid, | |||
| 3612 | } | 3613 | } |
| 3613 | } | 3614 | } |
| 3614 | 3615 | ||
| 3616 | #ifdef CONFIG_HAVE_MEMBLOCK | ||
| 3617 | u64 __init find_memory_core_early(int nid, u64 size, u64 align, | ||
| 3618 | u64 goal, u64 limit) | ||
| 3619 | { | ||
| 3620 | int i; | ||
| 3621 | |||
| 3622 | /* Need to go over early_node_map to find out good range for node */ | ||
| 3623 | for_each_active_range_index_in_nid(i, nid) { | ||
| 3624 | u64 addr; | ||
| 3625 | u64 ei_start, ei_last; | ||
| 3626 | u64 final_start, final_end; | ||
| 3627 | |||
| 3628 | ei_last = early_node_map[i].end_pfn; | ||
| 3629 | ei_last <<= PAGE_SHIFT; | ||
| 3630 | ei_start = early_node_map[i].start_pfn; | ||
| 3631 | ei_start <<= PAGE_SHIFT; | ||
| 3632 | |||
| 3633 | final_start = max(ei_start, goal); | ||
| 3634 | final_end = min(ei_last, limit); | ||
| 3635 | |||
| 3636 | if (final_start >= final_end) | ||
| 3637 | continue; | ||
| 3638 | |||
| 3639 | addr = memblock_find_in_range(final_start, final_end, size, align); | ||
| 3640 | |||
| 3641 | if (addr == MEMBLOCK_ERROR) | ||
| 3642 | continue; | ||
| 3643 | |||
| 3644 | return addr; | ||
| 3645 | } | ||
| 3646 | |||
| 3647 | return MEMBLOCK_ERROR; | ||
| 3648 | } | ||
| 3649 | #endif | ||
| 3650 | |||
| 3615 | int __init add_from_early_node_map(struct range *range, int az, | 3651 | int __init add_from_early_node_map(struct range *range, int az, |
| 3616 | int nr_range, int nid) | 3652 | int nr_range, int nid) |
| 3617 | { | 3653 | { |
