• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  	/* 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 successful to compact
39  	 * suitable pages.
40  	 */
41  	COMPACT_COMPLETE,
42  	/*
43  	 * direct compaction has scanned part of the zone but wasn't successful
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 terminated after concluding that the allocation
53  	 * should now succeed
54  	 */
55  	COMPACT_SUCCESS,
56  };
57  
58  struct alloc_context; /* in mm/internal.h */
59  
60  /*
61   * Number of free order-0 pages that should be available above given watermark
62   * to make sure compaction has reasonable chance of not running out of free
63   * pages that it needs to isolate as migration target during its work.
64   */
compact_gap(unsigned int order)65  static inline unsigned long compact_gap(unsigned int order)
66  {
67  	/*
68  	 * Although all the isolations for migration are temporary, compaction
69  	 * free scanner may have up to 1 << order pages on its list and then
70  	 * try to split an (order - 1) free page. At that point, a gap of
71  	 * 1 << order might not be enough, so it's safer to require twice that
72  	 * amount. Note that the number of pages on the list is also
73  	 * effectively limited by COMPACT_CLUSTER_MAX, as that's the maximum
74  	 * that the migrate scanner can have isolated on migrate list, and free
75  	 * scanner is only invoked when the number of isolated free pages is
76  	 * lower than that. But it's not worth to complicate the formula here
77  	 * as a bigger gap for higher orders than strictly necessary can also
78  	 * improve chances of compaction success.
79  	 */
80  	return 2UL << order;
81  }
82  
83  #ifdef CONFIG_COMPACTION
84  
85  extern unsigned int extfrag_for_order(struct zone *zone, unsigned int order);
86  extern int fragmentation_index(struct zone *zone, unsigned int order);
87  extern enum compact_result try_to_compact_pages(gfp_t gfp_mask,
88  		unsigned int order, unsigned int alloc_flags,
89  		const struct alloc_context *ac, enum compact_priority prio,
90  		struct page **page);
91  extern void reset_isolation_suitable(pg_data_t *pgdat);
92  extern bool compaction_suitable(struct zone *zone, int order,
93  					       int highest_zoneidx);
94  
95  extern void compaction_defer_reset(struct zone *zone, int order,
96  				bool alloc_success);
97  
98  bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
99  					int alloc_flags);
100  
101  extern void __meminit kcompactd_run(int nid);
102  extern void __meminit kcompactd_stop(int nid);
103  extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx);
104  extern unsigned long isolate_and_split_free_page(struct page *page,
105  				struct list_head *list);
106  extern void compact_node_async(int nid);
107  #else
reset_isolation_suitable(pg_data_t * pgdat)108  static inline void reset_isolation_suitable(pg_data_t *pgdat)
109  {
110  }
111  
compaction_suitable(struct zone * zone,int order,int highest_zoneidx)112  static inline bool compaction_suitable(struct zone *zone, int order,
113  						      int highest_zoneidx)
114  {
115  	return false;
116  }
117  
kcompactd_run(int nid)118  static inline void kcompactd_run(int nid)
119  {
120  }
kcompactd_stop(int nid)121  static inline void kcompactd_stop(int nid)
122  {
123  }
124  
wakeup_kcompactd(pg_data_t * pgdat,int order,int highest_zoneidx)125  static inline void wakeup_kcompactd(pg_data_t *pgdat,
126  				int order, int highest_zoneidx)
127  {
128  }
129  
isolate_and_split_free_page(struct page * page,struct list_head * list)130  static inline unsigned long isolate_and_split_free_page(struct page *page,
131  				struct list_head *list)
132  {
133  	return 0;
134  }
135  
136  #endif /* CONFIG_COMPACTION */
137  
138  struct node;
139  #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
140  extern int compaction_register_node(struct node *node);
141  extern void compaction_unregister_node(struct node *node);
142  
143  #else
144  
compaction_register_node(struct node * node)145  static inline int compaction_register_node(struct node *node)
146  {
147  	return 0;
148  }
149  
compaction_unregister_node(struct node * node)150  static inline void compaction_unregister_node(struct node *node)
151  {
152  }
153  #endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */
154  
155  #endif /* _LINUX_COMPACTION_H */
156