compaction.h 6.1 KB

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