linux/include/linux/compaction.h
<<
>>
Prefs
   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 */
 227