summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMel Gorman <mel@csn.ul.ie>2007-02-10 01:42:57 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 10:51:17 -0800
commita6af2bc3d5ce8722b9d09c5bdd5383c91c419653 (patch)
treed4af36e83f25d84979584b670b692068eb2b5a56
parente10a4437cb37c85f2df95432025b392d98aac2aa (diff)
downloadlinux-a6af2bc3d5ce8722b9d09c5bdd5383c91c419653.tar.gz
linux-a6af2bc3d5ce8722b9d09c5bdd5383c91c419653.tar.bz2
linux-a6af2bc3d5ce8722b9d09c5bdd5383c91c419653.zip
[PATCH] Avoid excessive sorting of early_node_map[]
find_min_pfn_for_node() and find_min_pfn_with_active_regions() sort early_node_map[] on every call. This is an excessive amount of sorting and that can be avoided. This patch always searches the whole early_node_map[] in find_min_pfn_for_node() instead of returning the first value found. The map is then only sorted once when required. Successfully boot tested on a number of machines. [akpm@osdl.org: cleanup] Signed-off-by: Mel Gorman <mel@csn.ul.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/page_alloc.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f12052dc23ff..f26fdc94393e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2877,20 +2877,23 @@ static void __init sort_node_map(void)
cmp_node_active_region, NULL);
}
-/* Find the lowest pfn for a node. This depends on a sorted early_node_map */
+/* Find the lowest pfn for a node */
unsigned long __init find_min_pfn_for_node(unsigned long nid)
{
int i;
-
- /* Regions in the early_node_map can be in any order */
- sort_node_map();
+ unsigned long min_pfn = ULONG_MAX;
/* Assuming a sorted map, the first range found has the starting pfn */
for_each_active_range_index_in_nid(i, nid)
- return early_node_map[i].start_pfn;
+ min_pfn = min(min_pfn, early_node_map[i].start_pfn);
- printk(KERN_WARNING "Could not find start_pfn for node %lu\n", nid);
- return 0;
+ if (min_pfn == ULONG_MAX) {
+ printk(KERN_WARNING
+ "Could not find start_pfn for node %lu\n", nid);
+ return 0;
+ }
+
+ return min_pfn;
}
/**
@@ -2939,6 +2942,9 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
unsigned long nid;
enum zone_type i;
+ /* Sort early_node_map as initialisation assumes it is sorted */
+ sort_node_map();
+
/* Record where the zone boundaries are */
memset(arch_zone_lowest_possible_pfn, 0,
sizeof(arch_zone_lowest_possible_pfn));