aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMel Gorman <mel@csn.ul.ie>2007-10-16 04:25:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:00 -0400
commit9ef9acb05a741ec10a5e9122717736de12adced9 (patch)
tree6008083999b3c6e115714fcdea637195f2b53df6
parente010487dbe09d63cf916fd1b119d17abd0f48207 (diff)
Do not group pages by mobility type on low memory systems
Grouping pages by mobility can only successfully operate when there are more MAX_ORDER_NR_PAGES areas than mobility types. When there are insufficient areas, fallbacks cannot be avoided. This has noticeable performance impacts on machines with small amounts of memory in comparison to MAX_ORDER_NR_PAGES. For example, on IA64 with a configuration including huge pages spans 1GiB with MAX_ORDER_NR_PAGES so would need at least 4GiB of RAM before grouping pages by mobility would be useful. In comparison, an x86 would need 16MB. This patch checks the size of vm_total_pages in build_all_zonelists(). If there are not enough areas, mobility is effectivly disabled by considering all allocations as the same type (UNMOVABLE). This is achived via a __read_mostly flag. With this patch, performance is comparable to disabling grouping pages by mobility at compile-time on a test machine with insufficient memory. With this patch, it is reasonable to get rid of grouping pages by mobility a compile-time option. Signed-off-by: Mel Gorman <mel@csn.ul.ie> Acked-by: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/page_alloc.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 03fef8d987f6..676aec93d699 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -159,8 +159,13 @@ EXPORT_SYMBOL(nr_node_ids);
159#endif 159#endif
160 160
161#ifdef CONFIG_PAGE_GROUP_BY_MOBILITY 161#ifdef CONFIG_PAGE_GROUP_BY_MOBILITY
162int page_group_by_mobility_disabled __read_mostly;
163
162static inline int get_pageblock_migratetype(struct page *page) 164static inline int get_pageblock_migratetype(struct page *page)
163{ 165{
166 if (unlikely(page_group_by_mobility_disabled))
167 return MIGRATE_UNMOVABLE;
168
164 return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end); 169 return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
165} 170}
166 171
@@ -174,6 +179,9 @@ static inline int allocflags_to_migratetype(gfp_t gfp_flags, int order)
174{ 179{
175 WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK); 180 WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
176 181
182 if (unlikely(page_group_by_mobility_disabled))
183 return MIGRATE_UNMOVABLE;
184
177 /* Cluster high-order atomic allocations together */ 185 /* Cluster high-order atomic allocations together */
178 if (unlikely(order > 0) && 186 if (unlikely(order > 0) &&
179 (!(gfp_flags & __GFP_WAIT) || in_interrupt())) 187 (!(gfp_flags & __GFP_WAIT) || in_interrupt()))
@@ -2375,9 +2383,23 @@ void build_all_zonelists(void)
2375 /* cpuset refresh routine should be here */ 2383 /* cpuset refresh routine should be here */
2376 } 2384 }
2377 vm_total_pages = nr_free_pagecache_pages(); 2385 vm_total_pages = nr_free_pagecache_pages();
2378 printk("Built %i zonelists in %s order. Total pages: %ld\n", 2386 /*
2387 * Disable grouping by mobility if the number of pages in the
2388 * system is too low to allow the mechanism to work. It would be
2389 * more accurate, but expensive to check per-zone. This check is
2390 * made on memory-hotadd so a system can start with mobility
2391 * disabled and enable it later
2392 */
2393 if (vm_total_pages < (MAX_ORDER_NR_PAGES * MIGRATE_TYPES))
2394 page_group_by_mobility_disabled = 1;
2395 else
2396 page_group_by_mobility_disabled = 0;
2397
2398 printk("Built %i zonelists in %s order, mobility grouping %s. "
2399 "Total pages: %ld\n",
2379 num_online_nodes(), 2400 num_online_nodes(),
2380 zonelist_order_name[current_zonelist_order], 2401 zonelist_order_name[current_zonelist_order],
2402 page_group_by_mobility_disabled ? "off" : "on",
2381 vm_total_pages); 2403 vm_total_pages);
2382#ifdef CONFIG_NUMA 2404#ifdef CONFIG_NUMA
2383 printk("Policy zone: %s\n", zone_names[policy_zone]); 2405 printk("Policy zone: %s\n", zone_names[policy_zone]);