xref: /linux-6.15/include/linux/shrinker.h (revision f04eba13)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2b0d40c92SDave Chinner #ifndef _LINUX_SHRINKER_H
3b0d40c92SDave Chinner #define _LINUX_SHRINKER_H
4b0d40c92SDave Chinner 
5b7217a0bST.J. Mercier #include <linux/atomic.h>
6b7217a0bST.J. Mercier #include <linux/types.h>
7ca1d36b8SQi Zheng #include <linux/refcount.h>
8ca1d36b8SQi Zheng #include <linux/completion.h>
9b7217a0bST.J. Mercier 
10307bececSQi Zheng #define SHRINKER_UNIT_BITS	BITS_PER_LONG
11307bececSQi Zheng 
12307bececSQi Zheng /*
13307bececSQi Zheng  * Bitmap and deferred work of shrinker::id corresponding to memcg-aware
14307bececSQi Zheng  * shrinkers, which have elements charged to the memcg.
15307bececSQi Zheng  */
16307bececSQi Zheng struct shrinker_info_unit {
17307bececSQi Zheng 	atomic_long_t nr_deferred[SHRINKER_UNIT_BITS];
18307bececSQi Zheng 	DECLARE_BITMAP(map, SHRINKER_UNIT_BITS);
19307bececSQi Zheng };
20307bececSQi Zheng 
21307bececSQi Zheng struct shrinker_info {
22307bececSQi Zheng 	struct rcu_head rcu;
23307bececSQi Zheng 	int map_nr_max;
24307bececSQi Zheng 	struct shrinker_info_unit *unit[];
25307bececSQi Zheng };
26307bececSQi Zheng 
27b0d40c92SDave Chinner /*
28b0d40c92SDave Chinner  * This struct is used to pass information from page reclaim to the shrinkers.
2906c88398SZhen Lei  * We consolidate the values for easier extension later.
3024f7c6b9SDave Chinner  *
3124f7c6b9SDave Chinner  * The 'gfpmask' refers to the allocation we are currently trying to
3224f7c6b9SDave Chinner  * fulfil.
33b0d40c92SDave Chinner  */
34b0d40c92SDave Chinner struct shrink_control {
35b0d40c92SDave Chinner 	gfp_t gfp_mask;
36b0d40c92SDave Chinner 
3792be775aSKirill Tkhai 	/* current node being shrunk (for NUMA aware shrinkers) */
3892be775aSKirill Tkhai 	int nid;
3992be775aSKirill Tkhai 
40a0b02131SDave Chinner 	/*
41a0b02131SDave Chinner 	 * How many objects scan_objects should scan and try to reclaim.
42a0b02131SDave Chinner 	 * This is reset before every call, so it is safe for callees
43a0b02131SDave Chinner 	 * to modify.
44a0b02131SDave Chinner 	 */
45b0d40c92SDave Chinner 	unsigned long nr_to_scan;
460ce3d744SDave Chinner 
47d460acb5SChris Wilson 	/*
48d460acb5SChris Wilson 	 * How many objects did scan_objects process?
49d460acb5SChris Wilson 	 * This defaults to nr_to_scan before every call, but the callee
50d460acb5SChris Wilson 	 * should track its actual progress.
51d460acb5SChris Wilson 	 */
52d460acb5SChris Wilson 	unsigned long nr_scanned;
53d460acb5SChris Wilson 
54cb731d6cSVladimir Davydov 	/* current memcg being shrunk (for memcg aware shrinkers) */
55cb731d6cSVladimir Davydov 	struct mem_cgroup *memcg;
56b0d40c92SDave Chinner };
57b0d40c92SDave Chinner 
5824f7c6b9SDave Chinner #define SHRINK_STOP (~0UL)
599b996468SKirill Tkhai #define SHRINK_EMPTY (~0UL - 1)
60b0d40c92SDave Chinner /*
61b0d40c92SDave Chinner  * A callback you can register to apply pressure to ageable caches.
62b0d40c92SDave Chinner  *
6324f7c6b9SDave Chinner  * @count_objects should return the number of freeable items in the cache. If
649b996468SKirill Tkhai  * there are no objects to free, it should return SHRINK_EMPTY, while 0 is
659b996468SKirill Tkhai  * returned in cases of the number of freeable items cannot be determined
669b996468SKirill Tkhai  * or shrinker should skip this cache for this time (e.g., their number
679b996468SKirill Tkhai  * is below shrinkable limit). No deadlock checks should be done during the
6824f7c6b9SDave Chinner  * count callback - the shrinker relies on aggregating scan counts that couldn't
6924f7c6b9SDave Chinner  * be executed due to potential deadlocks to be run at a later call when the
7024f7c6b9SDave Chinner  * deadlock condition is no longer pending.
71b0d40c92SDave Chinner  *
7224f7c6b9SDave Chinner  * @scan_objects will only be called if @count_objects returned a non-zero
7324f7c6b9SDave Chinner  * value for the number of freeable objects. The callout should scan the cache
7424f7c6b9SDave Chinner  * and attempt to free items from the cache. It should then return the number
7524f7c6b9SDave Chinner  * of objects freed during the scan, or SHRINK_STOP if progress cannot be made
7624f7c6b9SDave Chinner  * due to potential deadlocks. If SHRINK_STOP is returned, then no further
7724f7c6b9SDave Chinner  * attempts to call the @scan_objects will be made from the current reclaim
7824f7c6b9SDave Chinner  * context.
791d3d4437SGlauber Costa  *
801d3d4437SGlauber Costa  * @flags determine the shrinker abilities, like numa awareness
81b0d40c92SDave Chinner  */
82b0d40c92SDave Chinner struct shrinker {
8324f7c6b9SDave Chinner 	unsigned long (*count_objects)(struct shrinker *,
8424f7c6b9SDave Chinner 				       struct shrink_control *sc);
8524f7c6b9SDave Chinner 	unsigned long (*scan_objects)(struct shrinker *,
8624f7c6b9SDave Chinner 				      struct shrink_control *sc);
8724f7c6b9SDave Chinner 
88b0d40c92SDave Chinner 	long batch;	/* reclaim batch size, 0 = default */
89e50ef89bSKirill Tkhai 	int seeks;	/* seeks to recreate an obj */
90e50ef89bSKirill Tkhai 	unsigned flags;
91b0d40c92SDave Chinner 
92ca1d36b8SQi Zheng 	/*
93ca1d36b8SQi Zheng 	 * The reference count of this shrinker. Registered shrinker have an
94ca1d36b8SQi Zheng 	 * initial refcount of 1, then the lookup operations are now allowed
95ca1d36b8SQi Zheng 	 * to use it via shrinker_try_get(). Later in the unregistration step,
96ca1d36b8SQi Zheng 	 * the initial refcount will be discarded, and will free the shrinker
97ca1d36b8SQi Zheng 	 * asynchronously via RCU after its refcount reaches 0.
98ca1d36b8SQi Zheng 	 */
99ca1d36b8SQi Zheng 	refcount_t refcount;
100ca1d36b8SQi Zheng 	struct completion done;	/* use to wait for refcount to reach 0 */
101ca1d36b8SQi Zheng 	struct rcu_head rcu;
102ca1d36b8SQi Zheng 
103c42d50aeSQi Zheng 	void *private_data;
104c42d50aeSQi Zheng 
105b0d40c92SDave Chinner 	/* These are for internal use */
106b0d40c92SDave Chinner 	struct list_head list;
1070a432dcbSYang Shi #ifdef CONFIG_MEMCG
108b4c2b231SKirill Tkhai 	/* ID in shrinker_idr */
109b4c2b231SKirill Tkhai 	int id;
110b4c2b231SKirill Tkhai #endif
1115035ebc6SRoman Gushchin #ifdef CONFIG_SHRINKER_DEBUG
1125035ebc6SRoman Gushchin 	int debugfs_id;
113e33c267aSRoman Gushchin 	const char *name;
1145035ebc6SRoman Gushchin 	struct dentry *debugfs_entry;
1155035ebc6SRoman Gushchin #endif
1161d3d4437SGlauber Costa 	/* objs pending delete, per node */
1171d3d4437SGlauber Costa 	atomic_long_t *nr_deferred;
118b0d40c92SDave Chinner };
119b0d40c92SDave Chinner #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */
1201d3d4437SGlauber Costa 
121c42d50aeSQi Zheng /* Internal flags */
122c42d50aeSQi Zheng #define SHRINKER_REGISTERED	BIT(0)
123c42d50aeSQi Zheng #define SHRINKER_ALLOCATED	BIT(1)
124c42d50aeSQi Zheng 
125c42d50aeSQi Zheng /* Flags for users to use */
126c42d50aeSQi Zheng #define SHRINKER_NUMA_AWARE	BIT(2)
127c42d50aeSQi Zheng #define SHRINKER_MEMCG_AWARE	BIT(3)
1280a432dcbSYang Shi /*
1290a432dcbSYang Shi  * It just makes sense when the shrinker is also MEMCG_AWARE for now,
1300a432dcbSYang Shi  * non-MEMCG_AWARE shrinker should not have this flag set.
1310a432dcbSYang Shi  */
132c42d50aeSQi Zheng #define SHRINKER_NONSLAB	BIT(4)
133c42d50aeSQi Zheng 
134*f04eba13SLucy Mielke __printf(2, 3)
135c42d50aeSQi Zheng struct shrinker *shrinker_alloc(unsigned int flags, const char *fmt, ...);
136c42d50aeSQi Zheng void shrinker_register(struct shrinker *shrinker);
137c42d50aeSQi Zheng void shrinker_free(struct shrinker *shrinker);
1381d3d4437SGlauber Costa 
shrinker_try_get(struct shrinker * shrinker)139ca1d36b8SQi Zheng static inline bool shrinker_try_get(struct shrinker *shrinker)
140ca1d36b8SQi Zheng {
141ca1d36b8SQi Zheng 	return refcount_inc_not_zero(&shrinker->refcount);
142ca1d36b8SQi Zheng }
143ca1d36b8SQi Zheng 
shrinker_put(struct shrinker * shrinker)144ca1d36b8SQi Zheng static inline void shrinker_put(struct shrinker *shrinker)
145ca1d36b8SQi Zheng {
146ca1d36b8SQi Zheng 	if (refcount_dec_and_test(&shrinker->refcount))
147ca1d36b8SQi Zheng 		complete(&shrinker->done);
148ca1d36b8SQi Zheng }
149ca1d36b8SQi Zheng 
1505035ebc6SRoman Gushchin #ifdef CONFIG_SHRINKER_DEBUG
151e33c267aSRoman Gushchin extern int __printf(2, 3) shrinker_debugfs_rename(struct shrinker *shrinker,
152e33c267aSRoman Gushchin 						  const char *fmt, ...);
1535035ebc6SRoman Gushchin #else /* CONFIG_SHRINKER_DEBUG */
154e33c267aSRoman Gushchin static inline __printf(2, 3)
shrinker_debugfs_rename(struct shrinker * shrinker,const char * fmt,...)155e33c267aSRoman Gushchin int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
156e33c267aSRoman Gushchin {
157e33c267aSRoman Gushchin 	return 0;
158e33c267aSRoman Gushchin }
1595035ebc6SRoman Gushchin #endif /* CONFIG_SHRINKER_DEBUG */
1605035ebc6SRoman Gushchin #endif /* _LINUX_SHRINKER_H */
161