diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-02-10 04:20:20 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-12 12:41:59 -0500 |
commit | 08677214e318297f228237be0042aac754f48f1d (patch) | |
tree | 6d03424f7e287fcf66136b44512328afb1aeee49 /mm/page_alloc.c | |
parent | c252a5bb1f57afb1e336d68085217727ca7b2134 (diff) |
x86: Make 64 bit use early_res instead of bootmem before slab
Finally we can use early_res to replace bootmem for x86_64 now.
Still can use CONFIG_NO_BOOTMEM to enable it or not.
-v2: fix 32bit compiling about MAX_DMA32_PFN
-v3: folded bug fix from LKML message below
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <4B747239.4070907@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8deb9d0fd5b1..78821a28e394 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3435,6 +3435,59 @@ void __init free_bootmem_with_active_regions(int nid, | |||
3435 | } | 3435 | } |
3436 | } | 3436 | } |
3437 | 3437 | ||
3438 | int __init add_from_early_node_map(struct range *range, int az, | ||
3439 | int nr_range, int nid) | ||
3440 | { | ||
3441 | int i; | ||
3442 | u64 start, end; | ||
3443 | |||
3444 | /* need to go over early_node_map to find out good range for node */ | ||
3445 | for_each_active_range_index_in_nid(i, nid) { | ||
3446 | start = early_node_map[i].start_pfn; | ||
3447 | end = early_node_map[i].end_pfn; | ||
3448 | nr_range = add_range(range, az, nr_range, start, end); | ||
3449 | } | ||
3450 | return nr_range; | ||
3451 | } | ||
3452 | |||
3453 | void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, | ||
3454 | u64 goal, u64 limit) | ||
3455 | { | ||
3456 | int i; | ||
3457 | void *ptr; | ||
3458 | |||
3459 | /* need to go over early_node_map to find out good range for node */ | ||
3460 | for_each_active_range_index_in_nid(i, nid) { | ||
3461 | u64 addr; | ||
3462 | u64 ei_start, ei_last; | ||
3463 | |||
3464 | ei_last = early_node_map[i].end_pfn; | ||
3465 | ei_last <<= PAGE_SHIFT; | ||
3466 | ei_start = early_node_map[i].start_pfn; | ||
3467 | ei_start <<= PAGE_SHIFT; | ||
3468 | addr = find_early_area(ei_start, ei_last, | ||
3469 | goal, limit, size, align); | ||
3470 | |||
3471 | if (addr == -1ULL) | ||
3472 | continue; | ||
3473 | |||
3474 | #if 0 | ||
3475 | printk(KERN_DEBUG "alloc (nid=%d %llx - %llx) (%llx - %llx) %llx %llx => %llx\n", | ||
3476 | nid, | ||
3477 | ei_start, ei_last, goal, limit, size, | ||
3478 | align, addr); | ||
3479 | #endif | ||
3480 | |||
3481 | ptr = phys_to_virt(addr); | ||
3482 | memset(ptr, 0, size); | ||
3483 | reserve_early_without_check(addr, addr + size, "BOOTMEM"); | ||
3484 | return ptr; | ||
3485 | } | ||
3486 | |||
3487 | return NULL; | ||
3488 | } | ||
3489 | |||
3490 | |||
3438 | void __init work_with_active_regions(int nid, work_fn_t work_fn, void *data) | 3491 | void __init work_with_active_regions(int nid, work_fn_t work_fn, void *data) |
3439 | { | 3492 | { |
3440 | int i; | 3493 | int i; |
@@ -4467,7 +4520,11 @@ void __init set_dma_reserve(unsigned long new_dma_reserve) | |||
4467 | } | 4520 | } |
4468 | 4521 | ||
4469 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 4522 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
4470 | struct pglist_data __refdata contig_page_data = { .bdata = &bootmem_node_data[0] }; | 4523 | struct pglist_data __refdata contig_page_data = { |
4524 | #ifndef CONFIG_NO_BOOTMEM | ||
4525 | .bdata = &bootmem_node_data[0] | ||
4526 | #endif | ||
4527 | }; | ||
4471 | EXPORT_SYMBOL(contig_page_data); | 4528 | EXPORT_SYMBOL(contig_page_data); |
4472 | #endif | 4529 | #endif |
4473 | 4530 | ||