aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmstat.c
diff options
context:
space:
mode:
authorMel Gorman <mel@csn.ul.ie>2010-05-24 17:32:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:06:59 -0400
commit56de7263fcf3eb10c8dcdf8d59a9cec831795f3f (patch)
tree164637c0b678e20adfdcec4129563d9234faf405 /mm/vmstat.c
parented4a6d7f0676db50b5023cc01f6cda82a2f2a307 (diff)
mm: compaction: direct compact when a high-order allocation fails
Ordinarily when a high-order allocation fails, direct reclaim is entered to free pages to satisfy the allocation. With this patch, it is determined if an allocation failed due to external fragmentation instead of low memory and if so, the calling process will compact until a suitable page is freed. Compaction by moving pages in memory is considerably cheaper than paging out to disk and works where there are locked pages or no swap. If compaction fails to free a page of a suitable size, then reclaim will still occur. Direct compaction returns as soon as possible. As each block is compacted, it is checked if a suitable page has been freed and if so, it returns. [akpm@linux-foundation.org: Fix build errors] [aarcange@redhat.com: fix count_vm_event preempt in memory compaction direct reclaim] Signed-off-by: Mel Gorman <mel@csn.ul.ie> Acked-by: Rik van Riel <riel@redhat.com> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmstat.c')
-rw-r--r--mm/vmstat.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c
index c6aacf51b554..7759941d4e77 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -429,7 +429,7 @@ static void fill_contig_page_info(struct zone *zone,
429 * The value can be used to determine if page reclaim or compaction 429 * The value can be used to determine if page reclaim or compaction
430 * should be used 430 * should be used
431 */ 431 */
432int fragmentation_index(unsigned int order, struct contig_page_info *info) 432static int __fragmentation_index(unsigned int order, struct contig_page_info *info)
433{ 433{
434 unsigned long requested = 1UL << order; 434 unsigned long requested = 1UL << order;
435 435
@@ -448,6 +448,15 @@ int fragmentation_index(unsigned int order, struct contig_page_info *info)
448 */ 448 */
449 return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total); 449 return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total);
450} 450}
451
452/* Same as __fragmentation index but allocs contig_page_info on stack */
453int fragmentation_index(struct zone *zone, unsigned int order)
454{
455 struct contig_page_info info;
456
457 fill_contig_page_info(zone, order, &info);
458 return __fragmentation_index(order, &info);
459}
451#endif 460#endif
452 461
453#if defined(CONFIG_PROC_FS) || defined(CONFIG_COMPACTION) 462#if defined(CONFIG_PROC_FS) || defined(CONFIG_COMPACTION)
@@ -771,6 +780,9 @@ static const char * const vmstat_text[] = {
771 "compact_blocks_moved", 780 "compact_blocks_moved",
772 "compact_pages_moved", 781 "compact_pages_moved",
773 "compact_pagemigrate_failed", 782 "compact_pagemigrate_failed",
783 "compact_stall",
784 "compact_fail",
785 "compact_success",
774#endif 786#endif
775 787
776#ifdef CONFIG_HUGETLB_PAGE 788#ifdef CONFIG_HUGETLB_PAGE
@@ -1136,7 +1148,7 @@ static void extfrag_show_print(struct seq_file *m,
1136 zone->name); 1148 zone->name);
1137 for (order = 0; order < MAX_ORDER; ++order) { 1149 for (order = 0; order < MAX_ORDER; ++order) {
1138 fill_contig_page_info(zone, order, &info); 1150 fill_contig_page_info(zone, order, &info);
1139 index = fragmentation_index(order, &info); 1151 index = __fragmentation_index(order, &info);
1140 seq_printf(m, "%d.%03d ", index / 1000, index % 1000); 1152 seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
1141 } 1153 }
1142 1154