root/include/linux/compaction.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. compact_gap
  2. compaction_made_progress
  3. compaction_failed
  4. compaction_needs_reclaim
  5. compaction_withdrawn
  6. reset_isolation_suitable
  7. compaction_suitable
  8. defer_compaction
  9. compaction_deferred
  10. compaction_made_progress
  11. compaction_failed
  12. compaction_needs_reclaim
  13. compaction_withdrawn
  14. kcompactd_run
  15. kcompactd_stop
  16. wakeup_kcompactd
  17. compaction_register_node
  18. compaction_unregister_node

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _LINUX_COMPACTION_H
   3 #define _LINUX_COMPACTION_H
   4 
   5 /*
   6  * Determines how hard direct compaction should try to succeed.
   7  * Lower value means higher priority, analogically to reclaim priority.
   8  */
   9 enum compact_priority {
  10         COMPACT_PRIO_SYNC_FULL,
  11         MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_FULL,
  12         COMPACT_PRIO_SYNC_LIGHT,
  13         MIN_COMPACT_COSTLY_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
  14         DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
  15         COMPACT_PRIO_ASYNC,
  16         INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC
  17 };
  18 
  19 /* Return values for compact_zone() and try_to_compact_pages() */
  20 /* When adding new states, please adjust include/trace/events/compaction.h */
  21 enum compact_result {
  22         /* For more detailed tracepoint output - internal to compaction */
  23         COMPACT_NOT_SUITABLE_ZONE,
  24         /*
  25          * compaction didn't start as it was not possible or direct reclaim
  26          * was more suitable
  27          */
  28         COMPACT_SKIPPED,
  29         /* compaction didn't start as it was deferred due to past failures */
  30         COMPACT_DEFERRED,
  31 
  32         /* compaction not active last round */
  33         COMPACT_INACTIVE = COMPACT_DEFERRED,
  34 
  35         /* For more detailed tracepoint output - internal to compaction */
  36         COMPACT_NO_SUITABLE_PAGE,
  37         /* compaction should continue to another pageblock */
  38         COMPACT_CONTINUE,
  39 
  40         /*
  41          * The full zone was compacted scanned but wasn't successfull to compact
  42          * suitable pages.
  43          */
  44         COMPACT_COMPLETE,
  45         /*
  46          * direct compaction has scanned part of the zone but wasn't successfull
  47          * to compact suitable pages.
  48          */
  49         COMPACT_PARTIAL_SKIPPED,
  50 
  51         /* compaction terminated prematurely due to lock contentions */
  52         COMPACT_CONTENDED,
  53 
  54         /*
  55          * direct compaction terminated after concluding that the allocation
  56          * should now succeed
  57          */
  58         COMPACT_SUCCESS,
  59 };
  60 
  61 struct alloc_context; /* in mm/internal.h */
  62 
  63 /*
  64  * Number of free order-0 pages that should be available above given watermark
  65  * to make sure compaction has reasonable chance of not running out of free
  66  * pages that it needs to isolate as migration target during its work.
  67  */
  68 static inline unsigned long compact_gap(unsigned int order)
  69 {
  70         /*
  71          * Although all the isolations for migration are temporary, compaction
  72          * free scanner may have up to 1 << order pages on its list and then
  73          * try to split an (order - 1) free page. At that point, a gap of
  74          * 1 << order might not be enough, so it's safer to require twice that
  75          * amount. Note that the number of pages on the list is also
  76          * effectively limited by COMPACT_CLUSTER_MAX, as that's the maximum
  77          * that the migrate scanner can have isolated on migrate list, and free
  78          * scanner is only invoked when the number of isolated free pages is
  79          * lower than that. But it's not worth to complicate the formula here
  80          * as a bigger gap for higher orders than strictly necessary can also
  81          * improve chances of compaction success.
  82          */
  83         return 2UL << order;
  84 }
  85 
  86 #ifdef CONFIG_COMPACTION
  87 extern int sysctl_compact_memory;
  88 extern int sysctl_compaction_handler(struct ctl_table *table, int write,
  89                         void __user *buffer, size_t *length, loff_t *ppos);
  90 extern int sysctl_extfrag_threshold;
  91 extern int sysctl_compact_unevictable_allowed;
  92 
  93 extern int fragmentation_index(struct zone *zone, unsigned int order);
  94 extern enum compact_result try_to_compact_pages(gfp_t gfp_mask,
  95                 unsigned int order, unsigned int alloc_flags,
  96                 const struct alloc_context *ac, enum compact_priority prio,
  97                 struct page **page);
  98 extern void reset_isolation_suitable(pg_data_t *pgdat);
  99 extern enum compact_result compaction_suitable(struct zone *zone, int order,
 100                 unsigned int alloc_flags, int classzone_idx);
 101 
 102 extern void defer_compaction(struct zone *zone, int order);
 103 extern bool compaction_deferred(struct zone *zone, int order);
 104 extern void compaction_defer_reset(struct zone *zone, int order,
 105                                 bool alloc_success);
 106 extern bool compaction_restarting(struct zone *zone, int order);
 107 
 108 /* Compaction has made some progress and retrying makes sense */
 109 static inline bool compaction_made_progress(enum compact_result result)
 110 {
 111         /*
 112          * Even though this might sound confusing this in fact tells us
 113          * that the compaction successfully isolated and migrated some
 114          * pageblocks.
 115          */
 116         if (result == COMPACT_SUCCESS)
 117                 return true;
 118 
 119         return false;
 120 }
 121 
 122 /* Compaction has failed and it doesn't make much sense to keep retrying. */
 123 static inline bool compaction_failed(enum compact_result result)
 124 {
 125         /* All zones were scanned completely and still not result. */
 126         if (result == COMPACT_COMPLETE)
 127                 return true;
 128 
 129         return false;
 130 }
 131 
 132 /* Compaction needs reclaim to be performed first, so it can continue. */
 133 static inline bool compaction_needs_reclaim(enum compact_result result)
 134 {
 135         /*
 136          * Compaction backed off due to watermark checks for order-0
 137          * so the regular reclaim has to try harder and reclaim something.
 138          */
 139         if (result == COMPACT_SKIPPED)
 140                 return true;
 141 
 142         return false;
 143 }
 144 
 145 /*
 146  * Compaction has backed off for some reason after doing some work or none
 147  * at all. It might be throttling or lock contention. Retrying might be still
 148  * worthwhile, but with a higher priority if allowed.
 149  */
 150 static inline bool compaction_withdrawn(enum compact_result result)
 151 {
 152         /*
 153          * If compaction is deferred for high-order allocations, it is
 154          * because sync compaction recently failed. If this is the case
 155          * and the caller requested a THP allocation, we do not want
 156          * to heavily disrupt the system, so we fail the allocation
 157          * instead of entering direct reclaim.
 158          */
 159         if (result == COMPACT_DEFERRED)
 160                 return true;
 161 
 162         /*
 163          * If compaction in async mode encounters contention or blocks higher
 164          * priority task we back off early rather than cause stalls.
 165          */
 166         if (result == COMPACT_CONTENDED)
 167                 return true;
 168 
 169         /*
 170          * Page scanners have met but we haven't scanned full zones so this
 171          * is a back off in fact.
 172          */
 173         if (result == COMPACT_PARTIAL_SKIPPED)
 174                 return true;
 175 
 176         return false;
 177 }
 178 
 179 
 180 bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
 181                                         int alloc_flags);
 182 
 183 extern int kcompactd_run(int nid);
 184 extern void kcompactd_stop(int nid);
 185 extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx);
 186 
 187 #else
 188 static inline void reset_isolation_suitable(pg_data_t *pgdat)
 189 {
 190 }
 191 
 192 static inline enum compact_result compaction_suitable(struct zone *zone, int order,
 193                                         int alloc_flags, int classzone_idx)
 194 {
 195         return COMPACT_SKIPPED;
 196 }
 197 
 198 static inline void defer_compaction(struct zone *zone, int order)
 199 {
 200 }
 201 
 202 static inline bool compaction_deferred(struct zone *zone, int order)
 203 {
 204         return true;
 205 }
 206 
 207 static inline bool compaction_made_progress(enum compact_result result)
 208 {
 209         return false;
 210 }
 211 
 212 static inline bool compaction_failed(enum compact_result result)
 213 {
 214         return false;
 215 }
 216 
 217 static inline bool compaction_needs_reclaim(enum compact_result result)
 218 {
 219         return false;
 220 }
 221 
 222 static inline bool compaction_withdrawn(enum compact_result result)
 223 {
 224         return true;
 225 }
 226 
 227 static inline int kcompactd_run(int nid)
 228 {
 229         return 0;
 230 }
 231 static inline void kcompactd_stop(int nid)
 232 {
 233 }
 234 
 235 static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx)
 236 {
 237 }
 238 
 239 #endif /* CONFIG_COMPACTION */
 240 
 241 struct node;
 242 #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
 243 extern int compaction_register_node(struct node *node);
 244 extern void compaction_unregister_node(struct node *node);
 245 
 246 #else
 247 
 248 static inline int compaction_register_node(struct node *node)
 249 {
 250         return 0;
 251 }
 252 
 253 static inline void compaction_unregister_node(struct node *node)
 254 {
 255 }
 256 #endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */
 257 
 258 #endif /* _LINUX_COMPACTION_H */

/* [<][>][^][v][top][bottom][index][help] */