xref: /openbmc/linux/include/linux/compaction.h (revision 833dfc00)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2748446bbSMel Gorman #ifndef _LINUX_COMPACTION_H
3748446bbSMel Gorman #define _LINUX_COMPACTION_H
4748446bbSMel Gorman 
5a5508cd8SVlastimil Babka /*
6a5508cd8SVlastimil Babka  * Determines how hard direct compaction should try to succeed.
7a5508cd8SVlastimil Babka  * Lower value means higher priority, analogically to reclaim priority.
8a5508cd8SVlastimil Babka  */
9a5508cd8SVlastimil Babka enum compact_priority {
10a8e025e5SVlastimil Babka 	COMPACT_PRIO_SYNC_FULL,
11a8e025e5SVlastimil Babka 	MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_FULL,
12a5508cd8SVlastimil Babka 	COMPACT_PRIO_SYNC_LIGHT,
13c2033b00SVlastimil Babka 	MIN_COMPACT_COSTLY_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
14a5508cd8SVlastimil Babka 	DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
15a5508cd8SVlastimil Babka 	COMPACT_PRIO_ASYNC,
16a5508cd8SVlastimil Babka 	INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC
17a5508cd8SVlastimil Babka };
18a5508cd8SVlastimil Babka 
1956de7263SMel Gorman /* Return values for compact_zone() and try_to_compact_pages() */
20fa6c7b46SVlastimil Babka /* When adding new states, please adjust include/trace/events/compaction.h */
21ea7ab982SMichal Hocko enum compact_result {
224f9a358cSMichal Hocko 	/* For more detailed tracepoint output - internal to compaction */
234f9a358cSMichal Hocko 	COMPACT_NOT_SUITABLE_ZONE,
24ea7ab982SMichal Hocko 	/*
25ea7ab982SMichal Hocko 	 * compaction didn't start as it was not possible or direct reclaim
26ea7ab982SMichal Hocko 	 * was more suitable
27ea7ab982SMichal Hocko 	 */
28ea7ab982SMichal Hocko 	COMPACT_SKIPPED,
291d4746d3SMichal Hocko 	/* compaction didn't start as it was deferred due to past failures */
301d4746d3SMichal Hocko 	COMPACT_DEFERRED,
314f9a358cSMichal Hocko 
324f9a358cSMichal Hocko 	/* For more detailed tracepoint output - internal to compaction */
334f9a358cSMichal Hocko 	COMPACT_NO_SUITABLE_PAGE,
34ea7ab982SMichal Hocko 	/* compaction should continue to another pageblock */
35ea7ab982SMichal Hocko 	COMPACT_CONTINUE,
364f9a358cSMichal Hocko 
37c8f7de0bSMichal Hocko 	/*
3806c88398SZhen Lei 	 * The full zone was compacted scanned but wasn't successful to compact
39c8f7de0bSMichal Hocko 	 * suitable pages.
40c8f7de0bSMichal Hocko 	 */
41ea7ab982SMichal Hocko 	COMPACT_COMPLETE,
424f9a358cSMichal Hocko 	/*
4306c88398SZhen Lei 	 * direct compaction has scanned part of the zone but wasn't successful
444f9a358cSMichal Hocko 	 * to compact suitable pages.
454f9a358cSMichal Hocko 	 */
464f9a358cSMichal Hocko 	COMPACT_PARTIAL_SKIPPED,
474f9a358cSMichal Hocko 
484f9a358cSMichal Hocko 	/* compaction terminated prematurely due to lock contentions */
49ea7ab982SMichal Hocko 	COMPACT_CONTENDED,
504f9a358cSMichal Hocko 
514f9a358cSMichal Hocko 	/*
52cf378319SVlastimil Babka 	 * direct compaction terminated after concluding that the allocation
53cf378319SVlastimil Babka 	 * should now succeed
544f9a358cSMichal Hocko 	 */
55cf378319SVlastimil Babka 	COMPACT_SUCCESS,
56ea7ab982SMichal Hocko };
57748446bbSMel Gorman 
581a6d53a1SVlastimil Babka struct alloc_context; /* in mm/internal.h */
591a6d53a1SVlastimil Babka 
609861a62cSVlastimil Babka /*
619861a62cSVlastimil Babka  * Number of free order-0 pages that should be available above given watermark
629861a62cSVlastimil Babka  * to make sure compaction has reasonable chance of not running out of free
639861a62cSVlastimil Babka  * pages that it needs to isolate as migration target during its work.
649861a62cSVlastimil Babka  */
compact_gap(unsigned int order)659861a62cSVlastimil Babka static inline unsigned long compact_gap(unsigned int order)
669861a62cSVlastimil Babka {
679861a62cSVlastimil Babka 	/*
689861a62cSVlastimil Babka 	 * Although all the isolations for migration are temporary, compaction
699861a62cSVlastimil Babka 	 * free scanner may have up to 1 << order pages on its list and then
709861a62cSVlastimil Babka 	 * try to split an (order - 1) free page. At that point, a gap of
719861a62cSVlastimil Babka 	 * 1 << order might not be enough, so it's safer to require twice that
729861a62cSVlastimil Babka 	 * amount. Note that the number of pages on the list is also
739861a62cSVlastimil Babka 	 * effectively limited by COMPACT_CLUSTER_MAX, as that's the maximum
749861a62cSVlastimil Babka 	 * that the migrate scanner can have isolated on migrate list, and free
759861a62cSVlastimil Babka 	 * scanner is only invoked when the number of isolated free pages is
769861a62cSVlastimil Babka 	 * lower than that. But it's not worth to complicate the formula here
779861a62cSVlastimil Babka 	 * as a bigger gap for higher orders than strictly necessary can also
789861a62cSVlastimil Babka 	 * improve chances of compaction success.
799861a62cSVlastimil Babka 	 */
809861a62cSVlastimil Babka 	return 2UL << order;
819861a62cSVlastimil Babka }
829861a62cSVlastimil Babka 
8376ab0f53SMel Gorman #ifdef CONFIG_COMPACTION
8456de7263SMel Gorman 
85d34c0a75SNitin Gupta extern unsigned int extfrag_for_order(struct zone *zone, unsigned int order);
8656de7263SMel Gorman extern int fragmentation_index(struct zone *zone, unsigned int order);
87ea7ab982SMichal Hocko extern enum compact_result try_to_compact_pages(gfp_t gfp_mask,
88c3486f53SVlastimil Babka 		unsigned int order, unsigned int alloc_flags,
895e1f0f09SMel Gorman 		const struct alloc_context *ac, enum compact_priority prio,
905e1f0f09SMel Gorman 		struct page **page);
9162997027SMel Gorman extern void reset_isolation_suitable(pg_data_t *pgdat);
923cf04937SJohannes Weiner extern bool compaction_suitable(struct zone *zone, int order,
93e8606320SJohannes Weiner 					       int highest_zoneidx);
944f92e258SMel Gorman 
9524e2716fSJoonsoo Kim extern void compaction_defer_reset(struct zone *zone, int order,
9624e2716fSJoonsoo Kim 				bool alloc_success);
9762997027SMel Gorman 
9886a294a8SMichal Hocko bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
9986a294a8SMichal Hocko 					int alloc_flags);
10086a294a8SMichal Hocko 
101*833dfc00SMiaohe Lin extern void __meminit kcompactd_run(int nid);
102*833dfc00SMiaohe Lin extern void __meminit kcompactd_stop(int nid);
10397a225e6SJoonsoo Kim extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx);
104698b1b30SVlastimil Babka 
10556de7263SMel Gorman #else
reset_isolation_suitable(pg_data_t * pgdat)10662997027SMel Gorman static inline void reset_isolation_suitable(pg_data_t *pgdat)
10762997027SMel Gorman {
10862997027SMel Gorman }
10962997027SMel Gorman 
compaction_suitable(struct zone * zone,int order,int highest_zoneidx)1103cf04937SJohannes Weiner static inline bool compaction_suitable(struct zone *zone, int order,
111e8606320SJohannes Weiner 						      int highest_zoneidx)
1123e7d3449SMel Gorman {
1133cf04937SJohannes Weiner 	return false;
1143e7d3449SMel Gorman }
1153e7d3449SMel Gorman 
kcompactd_run(int nid)116024c61eaSMiaohe Lin static inline void kcompactd_run(int nid)
117698b1b30SVlastimil Babka {
118698b1b30SVlastimil Babka }
kcompactd_stop(int nid)119698b1b30SVlastimil Babka static inline void kcompactd_stop(int nid)
120698b1b30SVlastimil Babka {
121698b1b30SVlastimil Babka }
122698b1b30SVlastimil Babka 
wakeup_kcompactd(pg_data_t * pgdat,int order,int highest_zoneidx)12397a225e6SJoonsoo Kim static inline void wakeup_kcompactd(pg_data_t *pgdat,
12497a225e6SJoonsoo Kim 				int order, int highest_zoneidx)
125698b1b30SVlastimil Babka {
126698b1b30SVlastimil Babka }
127698b1b30SVlastimil Babka 
12876ab0f53SMel Gorman #endif /* CONFIG_COMPACTION */
12976ab0f53SMel Gorman 
130bda807d4SMinchan Kim struct node;
131ace451ebSYu Zhao #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
132ed4a6d7fSMel Gorman extern int compaction_register_node(struct node *node);
133ed4a6d7fSMel Gorman extern void compaction_unregister_node(struct node *node);
134ed4a6d7fSMel Gorman 
135ed4a6d7fSMel Gorman #else
136ed4a6d7fSMel Gorman 
compaction_register_node(struct node * node)137ed4a6d7fSMel Gorman static inline int compaction_register_node(struct node *node)
138ed4a6d7fSMel Gorman {
139ed4a6d7fSMel Gorman 	return 0;
140ed4a6d7fSMel Gorman }
141ed4a6d7fSMel Gorman 
compaction_unregister_node(struct node * node)142ed4a6d7fSMel Gorman static inline void compaction_unregister_node(struct node *node)
143ed4a6d7fSMel Gorman {
144ed4a6d7fSMel Gorman }
145ed4a6d7fSMel Gorman #endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */
146ed4a6d7fSMel Gorman 
147748446bbSMel Gorman #endif /* _LINUX_COMPACTION_H */
148