148 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _LINUX_COMPACTION_H3#define _LINUX_COMPACTION_H4 5/*6 * Determines how hard direct compaction should try to succeed.7 * Lower value means higher priority, analogically to reclaim priority.8 */9enum 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_ASYNC17};18 19/* Return values for compact_zone() and try_to_compact_pages() */20/* When adding new states, please adjust include/trace/events/compaction.h */21enum 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 reclaim26 * was more suitable27 */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 compact39 * suitable pages.40 */41 COMPACT_COMPLETE,42 /*43 * direct compaction has scanned part of the zone but wasn't successful44 * 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 allocation53 * should now succeed54 */55 COMPACT_SUCCESS,56};57 58struct alloc_context; /* in mm/internal.h */59 60/*61 * Number of free order-0 pages that should be available above given watermark62 * to make sure compaction has reasonable chance of not running out of free63 * pages that it needs to isolate as migration target during its work.64 */65static inline unsigned long compact_gap(unsigned int order)66{67 /*68 * Although all the isolations for migration are temporary, compaction69 * free scanner may have up to 1 << order pages on its list and then70 * try to split an (order - 1) free page. At that point, a gap of71 * 1 << order might not be enough, so it's safer to require twice that72 * amount. Note that the number of pages on the list is also73 * effectively limited by COMPACT_CLUSTER_MAX, as that's the maximum74 * that the migrate scanner can have isolated on migrate list, and free75 * scanner is only invoked when the number of isolated free pages is76 * lower than that. But it's not worth to complicate the formula here77 * as a bigger gap for higher orders than strictly necessary can also78 * improve chances of compaction success.79 */80 return 2UL << order;81}82 83#ifdef CONFIG_COMPACTION84 85extern unsigned int extfrag_for_order(struct zone *zone, unsigned int order);86extern int fragmentation_index(struct zone *zone, unsigned int order);87extern 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) HWJS_SUSPENDS;91extern void reset_isolation_suitable(pg_data_t *pgdat) HWJS_SUSPENDS;92extern bool compaction_suitable(struct zone *zone, int order,93 int highest_zoneidx);94 95extern void compaction_defer_reset(struct zone *zone, int order,96 bool alloc_success);97 98bool compaction_zonelist_suitable(struct alloc_context *ac, int order,99 int alloc_flags);100 101extern void __meminit kcompactd_run(int nid) HWJS_SUSPENDS;102extern void __meminit kcompactd_stop(int nid) HWJS_SUSPENDS;103extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx) HWJS_SUSPENDS;104 105#else106static inline void reset_isolation_suitable(pg_data_t *pgdat)107{108}109 110static inline bool compaction_suitable(struct zone *zone, int order,111 int highest_zoneidx)112{113 return false;114}115 116static inline void kcompactd_run(int nid)117{118}119static inline void kcompactd_stop(int nid)120{121}122 123static inline void wakeup_kcompactd(pg_data_t *pgdat,124 int order, int highest_zoneidx)125{126}127 128#endif /* CONFIG_COMPACTION */129 130struct node;131#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)132extern int compaction_register_node(struct node *node);133extern void compaction_unregister_node(struct node *node);134 135#else136 137static inline int compaction_register_node(struct node *node)138{139 return 0;140}141 142static inline void compaction_unregister_node(struct node *node)143{144}145#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */146 147#endif /* _LINUX_COMPACTION_H */148