cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

compaction.h (7310B)


      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 */
      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_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 */
     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 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
     58struct 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 */
     65static 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
     84extern unsigned int sysctl_compaction_proactiveness;
     85extern int sysctl_compaction_handler(struct ctl_table *table, int write,
     86			void *buffer, size_t *length, loff_t *ppos);
     87extern int compaction_proactiveness_sysctl_handler(struct ctl_table *table,
     88		int write, void *buffer, size_t *length, loff_t *ppos);
     89extern int sysctl_extfrag_threshold;
     90extern int sysctl_compact_unevictable_allowed;
     91
     92extern unsigned int extfrag_for_order(struct zone *zone, unsigned int order);
     93extern int fragmentation_index(struct zone *zone, unsigned int order);
     94extern 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);
     98extern void reset_isolation_suitable(pg_data_t *pgdat);
     99extern enum compact_result compaction_suitable(struct zone *zone, int order,
    100		unsigned int alloc_flags, int highest_zoneidx);
    101
    102extern void compaction_defer_reset(struct zone *zone, int order,
    103				bool alloc_success);
    104
    105/* Compaction has made some progress and retrying makes sense */
    106static inline bool compaction_made_progress(enum compact_result result)
    107{
    108	/*
    109	 * Even though this might sound confusing this in fact tells us
    110	 * that the compaction successfully isolated and migrated some
    111	 * pageblocks.
    112	 */
    113	if (result == COMPACT_SUCCESS)
    114		return true;
    115
    116	return false;
    117}
    118
    119/* Compaction has failed and it doesn't make much sense to keep retrying. */
    120static inline bool compaction_failed(enum compact_result result)
    121{
    122	/* All zones were scanned completely and still not result. */
    123	if (result == COMPACT_COMPLETE)
    124		return true;
    125
    126	return false;
    127}
    128
    129/* Compaction needs reclaim to be performed first, so it can continue. */
    130static inline bool compaction_needs_reclaim(enum compact_result result)
    131{
    132	/*
    133	 * Compaction backed off due to watermark checks for order-0
    134	 * so the regular reclaim has to try harder and reclaim something.
    135	 */
    136	if (result == COMPACT_SKIPPED)
    137		return true;
    138
    139	return false;
    140}
    141
    142/*
    143 * Compaction has backed off for some reason after doing some work or none
    144 * at all. It might be throttling or lock contention. Retrying might be still
    145 * worthwhile, but with a higher priority if allowed.
    146 */
    147static inline bool compaction_withdrawn(enum compact_result result)
    148{
    149	/*
    150	 * If compaction is deferred for high-order allocations, it is
    151	 * because sync compaction recently failed. If this is the case
    152	 * and the caller requested a THP allocation, we do not want
    153	 * to heavily disrupt the system, so we fail the allocation
    154	 * instead of entering direct reclaim.
    155	 */
    156	if (result == COMPACT_DEFERRED)
    157		return true;
    158
    159	/*
    160	 * If compaction in async mode encounters contention or blocks higher
    161	 * priority task we back off early rather than cause stalls.
    162	 */
    163	if (result == COMPACT_CONTENDED)
    164		return true;
    165
    166	/*
    167	 * Page scanners have met but we haven't scanned full zones so this
    168	 * is a back off in fact.
    169	 */
    170	if (result == COMPACT_PARTIAL_SKIPPED)
    171		return true;
    172
    173	return false;
    174}
    175
    176
    177bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
    178					int alloc_flags);
    179
    180extern void kcompactd_run(int nid);
    181extern void kcompactd_stop(int nid);
    182extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx);
    183
    184#else
    185static inline void reset_isolation_suitable(pg_data_t *pgdat)
    186{
    187}
    188
    189static inline enum compact_result compaction_suitable(struct zone *zone, int order,
    190					int alloc_flags, int highest_zoneidx)
    191{
    192	return COMPACT_SKIPPED;
    193}
    194
    195static inline bool compaction_made_progress(enum compact_result result)
    196{
    197	return false;
    198}
    199
    200static inline bool compaction_failed(enum compact_result result)
    201{
    202	return false;
    203}
    204
    205static inline bool compaction_needs_reclaim(enum compact_result result)
    206{
    207	return false;
    208}
    209
    210static inline bool compaction_withdrawn(enum compact_result result)
    211{
    212	return true;
    213}
    214
    215static inline void kcompactd_run(int nid)
    216{
    217}
    218static inline void kcompactd_stop(int nid)
    219{
    220}
    221
    222static inline void wakeup_kcompactd(pg_data_t *pgdat,
    223				int order, int highest_zoneidx)
    224{
    225}
    226
    227#endif /* CONFIG_COMPACTION */
    228
    229struct node;
    230#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
    231extern int compaction_register_node(struct node *node);
    232extern void compaction_unregister_node(struct node *node);
    233
    234#else
    235
    236static inline int compaction_register_node(struct node *node)
    237{
    238	return 0;
    239}
    240
    241static inline void compaction_unregister_node(struct node *node)
    242{
    243}
    244#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */
    245
    246#endif /* _LINUX_COMPACTION_H */