compaction.h 6.2 KB

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