at v4.7-rc2 6.4 kB view raw
1#ifndef _LINUX_COMPACTION_H 2#define _LINUX_COMPACTION_H 3 4/* Return values for compact_zone() and try_to_compact_pages() */ 5/* When adding new states, please adjust include/trace/events/compaction.h */ 6enum compact_result { 7 /* For more detailed tracepoint output - internal to compaction */ 8 COMPACT_NOT_SUITABLE_ZONE, 9 /* 10 * compaction didn't start as it was not possible or direct reclaim 11 * was more suitable 12 */ 13 COMPACT_SKIPPED, 14 /* compaction didn't start as it was deferred due to past failures */ 15 COMPACT_DEFERRED, 16 17 /* compaction not active last round */ 18 COMPACT_INACTIVE = COMPACT_DEFERRED, 19 20 /* For more detailed tracepoint output - internal to compaction */ 21 COMPACT_NO_SUITABLE_PAGE, 22 /* compaction should continue to another pageblock */ 23 COMPACT_CONTINUE, 24 25 /* 26 * The full zone was compacted scanned but wasn't successfull to compact 27 * suitable pages. 28 */ 29 COMPACT_COMPLETE, 30 /* 31 * direct compaction has scanned part of the zone but wasn't successfull 32 * to compact suitable pages. 33 */ 34 COMPACT_PARTIAL_SKIPPED, 35 36 /* compaction terminated prematurely due to lock contentions */ 37 COMPACT_CONTENDED, 38 39 /* 40 * direct compaction partially compacted a zone and there might be 41 * suitable pages 42 */ 43 COMPACT_PARTIAL, 44}; 45 46/* Used to signal whether compaction detected need_sched() or lock contention */ 47/* No contention detected */ 48#define COMPACT_CONTENDED_NONE 0 49/* Either need_sched() was true or fatal signal pending */ 50#define COMPACT_CONTENDED_SCHED 1 51/* Zone lock or lru_lock was contended in async compaction */ 52#define COMPACT_CONTENDED_LOCK 2 53 54struct alloc_context; /* in mm/internal.h */ 55 56#ifdef CONFIG_COMPACTION 57extern int sysctl_compact_memory; 58extern int sysctl_compaction_handler(struct ctl_table *table, int write, 59 void __user *buffer, size_t *length, loff_t *ppos); 60extern int sysctl_extfrag_threshold; 61extern int sysctl_extfrag_handler(struct ctl_table *table, int write, 62 void __user *buffer, size_t *length, loff_t *ppos); 63extern int sysctl_compact_unevictable_allowed; 64 65extern int fragmentation_index(struct zone *zone, unsigned int order); 66extern enum compact_result try_to_compact_pages(gfp_t gfp_mask, 67 unsigned int order, 68 unsigned int alloc_flags, const struct alloc_context *ac, 69 enum migrate_mode mode, int *contended); 70extern void compact_pgdat(pg_data_t *pgdat, int order); 71extern void reset_isolation_suitable(pg_data_t *pgdat); 72extern enum compact_result compaction_suitable(struct zone *zone, int order, 73 unsigned int alloc_flags, int classzone_idx); 74 75extern void defer_compaction(struct zone *zone, int order); 76extern bool compaction_deferred(struct zone *zone, int order); 77extern void compaction_defer_reset(struct zone *zone, int order, 78 bool alloc_success); 79extern bool compaction_restarting(struct zone *zone, int order); 80 81/* Compaction has made some progress and retrying makes sense */ 82static inline bool compaction_made_progress(enum compact_result result) 83{ 84 /* 85 * Even though this might sound confusing this in fact tells us 86 * that the compaction successfully isolated and migrated some 87 * pageblocks. 88 */ 89 if (result == COMPACT_PARTIAL) 90 return true; 91 92 return false; 93} 94 95/* Compaction has failed and it doesn't make much sense to keep retrying. */ 96static inline bool compaction_failed(enum compact_result result) 97{ 98 /* All zones were scanned completely and still not result. */ 99 if (result == COMPACT_COMPLETE) 100 return true; 101 102 return false; 103} 104 105/* 106 * Compaction has backed off for some reason. It might be throttling or 107 * lock contention. Retrying is still worthwhile. 108 */ 109static inline bool compaction_withdrawn(enum compact_result result) 110{ 111 /* 112 * Compaction backed off due to watermark checks for order-0 113 * so the regular reclaim has to try harder and reclaim something. 114 */ 115 if (result == COMPACT_SKIPPED) 116 return true; 117 118 /* 119 * If compaction is deferred for high-order allocations, it is 120 * because sync compaction recently failed. If this is the case 121 * and the caller requested a THP allocation, we do not want 122 * to heavily disrupt the system, so we fail the allocation 123 * instead of entering direct reclaim. 124 */ 125 if (result == COMPACT_DEFERRED) 126 return true; 127 128 /* 129 * If compaction in async mode encounters contention or blocks higher 130 * priority task we back off early rather than cause stalls. 131 */ 132 if (result == COMPACT_CONTENDED) 133 return true; 134 135 /* 136 * Page scanners have met but we haven't scanned full zones so this 137 * is a back off in fact. 138 */ 139 if (result == COMPACT_PARTIAL_SKIPPED) 140 return true; 141 142 return false; 143} 144 145 146bool compaction_zonelist_suitable(struct alloc_context *ac, int order, 147 int alloc_flags); 148 149extern int kcompactd_run(int nid); 150extern void kcompactd_stop(int nid); 151extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx); 152 153#else 154static inline enum compact_result try_to_compact_pages(gfp_t gfp_mask, 155 unsigned int order, int alloc_flags, 156 const struct alloc_context *ac, 157 enum migrate_mode mode, int *contended) 158{ 159 return COMPACT_CONTINUE; 160} 161 162static inline void compact_pgdat(pg_data_t *pgdat, int order) 163{ 164} 165 166static inline void reset_isolation_suitable(pg_data_t *pgdat) 167{ 168} 169 170static inline enum compact_result compaction_suitable(struct zone *zone, int order, 171 int alloc_flags, int classzone_idx) 172{ 173 return COMPACT_SKIPPED; 174} 175 176static inline void defer_compaction(struct zone *zone, int order) 177{ 178} 179 180static inline bool compaction_deferred(struct zone *zone, int order) 181{ 182 return true; 183} 184 185static inline bool compaction_made_progress(enum compact_result result) 186{ 187 return false; 188} 189 190static inline bool compaction_failed(enum compact_result result) 191{ 192 return false; 193} 194 195static inline bool compaction_withdrawn(enum compact_result result) 196{ 197 return true; 198} 199 200static inline int kcompactd_run(int nid) 201{ 202 return 0; 203} 204static inline void kcompactd_stop(int nid) 205{ 206} 207 208static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx) 209{ 210} 211 212#endif /* CONFIG_COMPACTION */ 213 214#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) 215extern int compaction_register_node(struct node *node); 216extern void compaction_unregister_node(struct node *node); 217 218#else 219 220static inline int compaction_register_node(struct node *node) 221{ 222 return 0; 223} 224 225static inline void compaction_unregister_node(struct node *node) 226{ 227} 228#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */ 229 230#endif /* _LINUX_COMPACTION_H */