diff options
author | Mel Gorman <mel@csn.ul.ie> | 2010-05-24 17:32:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-25 11:06:59 -0400 |
commit | 56de7263fcf3eb10c8dcdf8d59a9cec831795f3f (patch) | |
tree | 164637c0b678e20adfdcec4129563d9234faf405 /include/linux/compaction.h | |
parent | ed4a6d7f0676db50b5023cc01f6cda82a2f2a307 (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 'include/linux/compaction.h')
-rw-r--r-- | include/linux/compaction.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/include/linux/compaction.h b/include/linux/compaction.h index ba98cfe0ae1..eed40ec4280 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h | |||
@@ -1,15 +1,31 @@ | |||
1 | #ifndef _LINUX_COMPACTION_H | 1 | #ifndef _LINUX_COMPACTION_H |
2 | #define _LINUX_COMPACTION_H | 2 | #define _LINUX_COMPACTION_H |
3 | 3 | ||
4 | /* Return values for compact_zone() */ | 4 | /* Return values for compact_zone() and try_to_compact_pages() */ |
5 | #define COMPACT_CONTINUE 0 | 5 | /* compaction didn't start as it was not possible or direct reclaim was more suitable */ |
6 | #define COMPACT_PARTIAL 1 | 6 | #define COMPACT_SKIPPED 0 |
7 | #define COMPACT_COMPLETE 2 | 7 | /* compaction should continue to another pageblock */ |
8 | #define COMPACT_CONTINUE 1 | ||
9 | /* direct compaction partially compacted a zone and there are suitable pages */ | ||
10 | #define COMPACT_PARTIAL 2 | ||
11 | /* The full zone was compacted */ | ||
12 | #define COMPACT_COMPLETE 3 | ||
8 | 13 | ||
9 | #ifdef CONFIG_COMPACTION | 14 | #ifdef CONFIG_COMPACTION |
10 | extern int sysctl_compact_memory; | 15 | extern int sysctl_compact_memory; |
11 | extern int sysctl_compaction_handler(struct ctl_table *table, int write, | 16 | extern int sysctl_compaction_handler(struct ctl_table *table, int write, |
12 | void __user *buffer, size_t *length, loff_t *ppos); | 17 | void __user *buffer, size_t *length, loff_t *ppos); |
18 | |||
19 | extern int fragmentation_index(struct zone *zone, unsigned int order); | ||
20 | extern unsigned long try_to_compact_pages(struct zonelist *zonelist, | ||
21 | int order, gfp_t gfp_mask, nodemask_t *mask); | ||
22 | #else | ||
23 | static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, | ||
24 | int order, gfp_t gfp_mask, nodemask_t *nodemask) | ||
25 | { | ||
26 | return COMPACT_CONTINUE; | ||
27 | } | ||
28 | |||
13 | #endif /* CONFIG_COMPACTION */ | 29 | #endif /* CONFIG_COMPACTION */ |
14 | 30 | ||
15 | #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) | 31 | #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) |