aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-12-17 19:59:07 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2010-12-29 17:46:55 -0500
commit1a4a678b12c84db9ae5dce424e0e97f0559bb57c (patch)
treec272694389a0b035f198be679eb9355788fc0e5c /mm/page_alloc.c
parent32e3f2b00c529477d26895c5428ed95bba537443 (diff)
memblock: Make find_memory_core_early() find from top-down
That is used for find ram in node or bootmem type. We should make it top-down so it will be consistent to memblock_find, and to avoid allocating potentially valuable low memory before we actually need it. Suggested-by: Jeremy Fitzhardinge <jeremy@goop.org> Signed-off-by: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <4D0C075B.3040501@kernel.org> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 07a654486f75..19413bfdef92 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3555,6 +3555,34 @@ static int __meminit next_active_region_index_in_nid(int index, int nid)
3555 return -1; 3555 return -1;
3556} 3556}
3557 3557
3558/*
3559 * Basic iterator support. Return the last range of PFNs for a node
3560 * Note: nid == MAX_NUMNODES returns last region regardless of node
3561 */
3562static int __meminit last_active_region_index_in_nid(int nid)
3563{
3564 int i;
3565
3566 for (i = nr_nodemap_entries - 1; i >= 0; i--)
3567 if (nid == MAX_NUMNODES || early_node_map[i].nid == nid)
3568 return i;
3569
3570 return -1;
3571}
3572
3573/*
3574 * Basic iterator support. Return the previous active range of PFNs for a node
3575 * Note: nid == MAX_NUMNODES returns next region regardless of node
3576 */
3577static int __meminit previous_active_region_index_in_nid(int index, int nid)
3578{
3579 for (index = index - 1; index >= 0; index--)
3580 if (nid == MAX_NUMNODES || early_node_map[index].nid == nid)
3581 return index;
3582
3583 return -1;
3584}
3585
3558#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID 3586#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
3559/* 3587/*
3560 * Required by SPARSEMEM. Given a PFN, return what node the PFN is on. 3588 * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
@@ -3606,6 +3634,10 @@ bool __meminit early_pfn_in_nid(unsigned long pfn, int node)
3606 for (i = first_active_region_index_in_nid(nid); i != -1; \ 3634 for (i = first_active_region_index_in_nid(nid); i != -1; \
3607 i = next_active_region_index_in_nid(i, nid)) 3635 i = next_active_region_index_in_nid(i, nid))
3608 3636
3637#define for_each_active_range_index_in_nid_reverse(i, nid) \
3638 for (i = last_active_region_index_in_nid(nid); i != -1; \
3639 i = previous_active_region_index_in_nid(i, nid))
3640
3609/** 3641/**
3610 * free_bootmem_with_active_regions - Call free_bootmem_node for each active range 3642 * free_bootmem_with_active_regions - Call free_bootmem_node for each active range
3611 * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed. 3643 * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed.
@@ -3644,7 +3676,7 @@ u64 __init find_memory_core_early(int nid, u64 size, u64 align,
3644 int i; 3676 int i;
3645 3677
3646 /* Need to go over early_node_map to find out good range for node */ 3678 /* Need to go over early_node_map to find out good range for node */
3647 for_each_active_range_index_in_nid(i, nid) { 3679 for_each_active_range_index_in_nid_reverse(i, nid) {
3648 u64 addr; 3680 u64 addr;
3649 u64 ei_start, ei_last; 3681 u64 ei_start, ei_last;
3650 u64 final_start, final_end; 3682 u64 final_start, final_end;