diff options
| author | Mel Gorman <mel@csn.ul.ie> | 2007-02-10 04:42:57 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 13:51:17 -0500 |
| commit | a6af2bc3d5ce8722b9d09c5bdd5383c91c419653 (patch) | |
| tree | d4af36e83f25d84979584b670b692068eb2b5a56 | |
| parent | e10a4437cb37c85f2df95432025b392d98aac2aa (diff) | |
[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.c | 20 |
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) | |||
| 2877 | cmp_node_active_region, NULL); | 2877 | cmp_node_active_region, NULL); |
| 2878 | } | 2878 | } |
| 2879 | 2879 | ||
| 2880 | /* Find the lowest pfn for a node. This depends on a sorted early_node_map */ | 2880 | /* Find the lowest pfn for a node */ |
| 2881 | unsigned long __init find_min_pfn_for_node(unsigned long nid) | 2881 | unsigned long __init find_min_pfn_for_node(unsigned long nid) |
| 2882 | { | 2882 | { |
| 2883 | int i; | 2883 | int i; |
| 2884 | 2884 | unsigned long min_pfn = ULONG_MAX; | |
| 2885 | /* Regions in the early_node_map can be in any order */ | ||
| 2886 | sort_node_map(); | ||
| 2887 | 2885 | ||
| 2888 | /* Assuming a sorted map, the first range found has the starting pfn */ | 2886 | /* Assuming a sorted map, the first range found has the starting pfn */ |
| 2889 | for_each_active_range_index_in_nid(i, nid) | 2887 | for_each_active_range_index_in_nid(i, nid) |
| 2890 | return early_node_map[i].start_pfn; | 2888 | min_pfn = min(min_pfn, early_node_map[i].start_pfn); |
| 2891 | 2889 | ||
| 2892 | printk(KERN_WARNING "Could not find start_pfn for node %lu\n", nid); | 2890 | if (min_pfn == ULONG_MAX) { |
| 2893 | return 0; | 2891 | printk(KERN_WARNING |
| 2892 | "Could not find start_pfn for node %lu\n", nid); | ||
| 2893 | return 0; | ||
| 2894 | } | ||
| 2895 | |||
| 2896 | return min_pfn; | ||
| 2894 | } | 2897 | } |
| 2895 | 2898 | ||
| 2896 | /** | 2899 | /** |
| @@ -2939,6 +2942,9 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn) | |||
| 2939 | unsigned long nid; | 2942 | unsigned long nid; |
| 2940 | enum zone_type i; | 2943 | enum zone_type i; |
| 2941 | 2944 | ||
| 2945 | /* Sort early_node_map as initialisation assumes it is sorted */ | ||
| 2946 | sort_node_map(); | ||
| 2947 | |||
| 2942 | /* Record where the zone boundaries are */ | 2948 | /* Record where the zone boundaries are */ |
| 2943 | memset(arch_zone_lowest_possible_pfn, 0, | 2949 | memset(arch_zone_lowest_possible_pfn, 0, |
| 2944 | sizeof(arch_zone_lowest_possible_pfn)); | 2950 | sizeof(arch_zone_lowest_possible_pfn)); |
