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