4 #include <linux/kthread.h>
5 #include <linux/list.h>
7 #include <linux/mutex.h>
8 #include <linux/shrinker.h>
10 #include "tools-util.h"
12 static LIST_HEAD(shrinker_list);
13 static DEFINE_MUTEX(shrinker_lock);
15 struct shrinker *shrinker_alloc(unsigned int flags, const char *fmt, ...)
17 return calloc(sizeof(struct shrinker), 1);
20 int shrinker_register(struct shrinker *shrinker)
22 mutex_lock(&shrinker_lock);
23 list_add_tail(&shrinker->list, &shrinker_list);
24 mutex_unlock(&shrinker_lock);
28 void unregister_shrinker(struct shrinker *shrinker)
30 mutex_lock(&shrinker_lock);
31 list_del(&shrinker->list);
32 mutex_unlock(&shrinker_lock);
40 static u64 parse_meminfo_line(const char *line)
44 if (sscanf(line, " %llu kB", &v) < 1)
49 void si_meminfo(struct sysinfo *val)
56 memset(val, 0, sizeof(*val));
59 f = fopen("/proc/meminfo", "r");
63 while ((len = getline(&line, &n, f)) != -1) {
64 if ((v = strcmp_prefix(line, "MemTotal:")))
65 val->totalram = parse_meminfo_line(v);
67 if ((v = strcmp_prefix(line, "MemAvailable:")))
68 val->freeram = parse_meminfo_line(v);
75 static void run_shrinkers_allocation_failed(gfp_t gfp_mask)
77 struct shrinker *shrinker;
79 mutex_lock(&shrinker_lock);
80 list_for_each_entry(shrinker, &shrinker_list, list) {
81 struct shrink_control sc = { .gfp_mask = gfp_mask, };
83 unsigned long have = shrinker->count_objects(shrinker, &sc);
85 sc.nr_to_scan = have / 8;
87 shrinker->scan_objects(shrinker, &sc);
89 mutex_unlock(&shrinker_lock);
92 void run_shrinkers(gfp_t gfp_mask, bool allocation_failed)
94 struct shrinker *shrinker;
98 if (!(gfp_mask & GFP_KERNEL))
101 /* Fast out if there are no shrinkers to run. */
102 if (list_empty(&shrinker_list))
105 if (allocation_failed) {
106 run_shrinkers_allocation_failed(gfp_mask);
112 if (info.totalram && info.freeram) {
113 want_shrink = (info.totalram >> 2) - info.freeram;
115 if (want_shrink <= 0)
118 /* If we weren't able to read /proc/meminfo, we must be pretty
121 want_shrink = 8 << 20;
124 mutex_lock(&shrinker_lock);
125 list_for_each_entry(shrinker, &shrinker_list, list) {
126 struct shrink_control sc = {
127 .gfp_mask = gfp_mask,
128 .nr_to_scan = want_shrink >> PAGE_SHIFT
131 shrinker->scan_objects(shrinker, &sc);
133 mutex_unlock(&shrinker_lock);
136 static int shrinker_thread(void *arg)
138 while (!kthread_should_stop()) {
142 clock_gettime(CLOCK_MONOTONIC, &to);
144 __set_current_state(TASK_INTERRUPTIBLE);
146 while ((v = READ_ONCE(current->state)) != TASK_RUNNING &&
148 futex(¤t->state, FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG,
149 v, &to, NULL, (uint32_t)~0);
150 if (kthread_should_stop())
152 if (v != TASK_RUNNING)
153 __set_current_state(TASK_RUNNING);
154 run_shrinkers(GFP_KERNEL, false);
160 struct task_struct *shrinker_task;
162 __attribute__((constructor(103)))
163 static void shrinker_thread_init(void)
165 shrinker_task = kthread_run(shrinker_thread, NULL, "shrinkers");
166 BUG_ON(IS_ERR(shrinker_task));
169 __attribute__((destructor(103)))
170 static void shrinker_thread_exit(void)
172 int ret = kthread_stop(shrinker_task);
175 shrinker_task = NULL;