aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/compaction.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/compaction.h')
-rw-r--r--include/linux/compaction.h86
1 files changed, 18 insertions, 68 deletions
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 3238ffa33f68..a014559e4a49 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -12,6 +12,10 @@
12#define COMPACT_PARTIAL 3 12#define COMPACT_PARTIAL 3
13/* The full zone was compacted */ 13/* The full zone was compacted */
14#define COMPACT_COMPLETE 4 14#define COMPACT_COMPLETE 4
15/* For more detailed tracepoint output */
16#define COMPACT_NO_SUITABLE_PAGE 5
17#define COMPACT_NOT_SUITABLE_ZONE 6
18/* When adding new state, please change compaction_status_string, too */
15 19
16/* Used to signal whether compaction detected need_sched() or lock contention */ 20/* Used to signal whether compaction detected need_sched() or lock contention */
17/* No contention detected */ 21/* No contention detected */
@@ -21,6 +25,8 @@
21/* Zone lock or lru_lock was contended in async compaction */ 25/* Zone lock or lru_lock was contended in async compaction */
22#define COMPACT_CONTENDED_LOCK 2 26#define COMPACT_CONTENDED_LOCK 2
23 27
28struct alloc_context; /* in mm/internal.h */
29
24#ifdef CONFIG_COMPACTION 30#ifdef CONFIG_COMPACTION
25extern int sysctl_compact_memory; 31extern int sysctl_compact_memory;
26extern int sysctl_compaction_handler(struct ctl_table *table, int write, 32extern int sysctl_compaction_handler(struct ctl_table *table, int write,
@@ -30,81 +36,25 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write,
30 void __user *buffer, size_t *length, loff_t *ppos); 36 void __user *buffer, size_t *length, loff_t *ppos);
31 37
32extern int fragmentation_index(struct zone *zone, unsigned int order); 38extern int fragmentation_index(struct zone *zone, unsigned int order);
33extern unsigned long try_to_compact_pages(struct zonelist *zonelist, 39extern unsigned long try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
34 int order, gfp_t gfp_mask, nodemask_t *mask, 40 int alloc_flags, const struct alloc_context *ac,
35 enum migrate_mode mode, int *contended, 41 enum migrate_mode mode, int *contended);
36 int alloc_flags, int classzone_idx);
37extern void compact_pgdat(pg_data_t *pgdat, int order); 42extern void compact_pgdat(pg_data_t *pgdat, int order);
38extern void reset_isolation_suitable(pg_data_t *pgdat); 43extern void reset_isolation_suitable(pg_data_t *pgdat);
39extern unsigned long compaction_suitable(struct zone *zone, int order, 44extern unsigned long compaction_suitable(struct zone *zone, int order,
40 int alloc_flags, int classzone_idx); 45 int alloc_flags, int classzone_idx);
41 46
42/* Do not skip compaction more than 64 times */ 47extern void defer_compaction(struct zone *zone, int order);
43#define COMPACT_MAX_DEFER_SHIFT 6 48extern bool compaction_deferred(struct zone *zone, int order);
44 49extern void compaction_defer_reset(struct zone *zone, int order,
45/* 50 bool alloc_success);
46 * Compaction is deferred when compaction fails to result in a page 51extern bool compaction_restarting(struct zone *zone, int order);
47 * allocation success. 1 << compact_defer_limit compactions are skipped up
48 * to a limit of 1 << COMPACT_MAX_DEFER_SHIFT
49 */
50static inline void defer_compaction(struct zone *zone, int order)
51{
52 zone->compact_considered = 0;
53 zone->compact_defer_shift++;
54
55 if (order < zone->compact_order_failed)
56 zone->compact_order_failed = order;
57
58 if (zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT)
59 zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT;
60}
61
62/* Returns true if compaction should be skipped this time */
63static inline bool compaction_deferred(struct zone *zone, int order)
64{
65 unsigned long defer_limit = 1UL << zone->compact_defer_shift;
66
67 if (order < zone->compact_order_failed)
68 return false;
69
70 /* Avoid possible overflow */
71 if (++zone->compact_considered > defer_limit)
72 zone->compact_considered = defer_limit;
73
74 return zone->compact_considered < defer_limit;
75}
76
77/*
78 * Update defer tracking counters after successful compaction of given order,
79 * which means an allocation either succeeded (alloc_success == true) or is
80 * expected to succeed.
81 */
82static inline void compaction_defer_reset(struct zone *zone, int order,
83 bool alloc_success)
84{
85 if (alloc_success) {
86 zone->compact_considered = 0;
87 zone->compact_defer_shift = 0;
88 }
89 if (order >= zone->compact_order_failed)
90 zone->compact_order_failed = order + 1;
91}
92
93/* Returns true if restarting compaction after many failures */
94static inline bool compaction_restarting(struct zone *zone, int order)
95{
96 if (order < zone->compact_order_failed)
97 return false;
98
99 return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT &&
100 zone->compact_considered >= 1UL << zone->compact_defer_shift;
101}
102 52
103#else 53#else
104static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, 54static inline unsigned long try_to_compact_pages(gfp_t gfp_mask,
105 int order, gfp_t gfp_mask, nodemask_t *nodemask, 55 unsigned int order, int alloc_flags,
106 enum migrate_mode mode, int *contended, 56 const struct alloc_context *ac,
107 int alloc_flags, int classzone_idx) 57 enum migrate_mode mode, int *contended)
108{ 58{
109 return COMPACT_CONTINUE; 59 return COMPACT_CONTINUE;
110} 60}