-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.c
135 lines (113 loc) · 3.85 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include "kresolv.h"
#define DEBUG if(flexfs_verbose >= 1)
static unsigned int flexfs_verbose = 0;
module_param_named(verbose, flexfs_verbose, uint, 0644);
static unsigned int flexdrop_min_mb = 0; /* minimum amount of MB that should always be free */
module_param_named(min_mb, flexdrop_min_mb, uint, 0644);
/* This module does the equivalent of a "echo 3 > /proc/sys/vm/drop_caches" until enough
* memory is available (in the output of "free -m").
* It was needed because of ZFS which was not not able to fully meets its configured memory cap
*/
static struct task_struct *gl_flexdrop_task;
static DECLARE_WAIT_QUEUE_HEAD(flexdrop_waitqueue);
static atomic_t flexdrop_wakeup;
static void flexdrop_check_memory(void)
{
struct sysinfo meminfo;
struct shrink_control shrink;
int nr_objects;
unsigned long free_mb;
int i;
si_meminfo(&meminfo);
free_mb = meminfo.freeram * meminfo.mem_unit / 1024 / 1024;
DEBUG printk(KERN_INFO "flexdrop freeram %lu MB (should be at least %u)\n", free_mb, flexdrop_min_mb);
if (free_mb >= flexdrop_min_mb)
{
DEBUG printk(KERN_INFO "enough memory is already free!\n");
return;
}
{
/* f_iterate_supers(f_drop_pagecache_sb, NULL); */
}
{
int nr_to_shrink = 10;
for (i = 0; i < 10; ++i)
{
/* from drop_slab() in linux/fs/drop_cache.c */
shrink = (struct shrink_control){ .gfp_mask = GFP_KERNEL, };
nr_objects = f_shrink_slab(&shrink, nr_to_shrink, nr_to_shrink);
DEBUG printk(KERN_INFO " dropped %d nr_objects\n", nr_objects);
if (nr_objects <= 0)
break;
si_meminfo(&meminfo);
free_mb = meminfo.freeram * meminfo.mem_unit / 1024 / 1024;
if (free_mb >= flexdrop_min_mb)
break;
if (nr_to_shrink < 1000)
nr_to_shrink *= 1000;
}
}
}
static int flexdrop_thread(void *data)
{
unsigned long jif; /* jiffies to wait */
printk(KERN_INFO "flexdrop thread started\n");
jif = msecs_to_jiffies(1000);
while (1)
{
/* msleep(1000); */
wait_event_timeout(flexdrop_waitqueue, atomic_read(&flexdrop_wakeup), jif);
DEBUG printk(KERN_INFO "flexdrop thread loop!\n");
if (atomic_read(&flexdrop_wakeup))
{
atomic_dec(&flexdrop_wakeup);
break;
}
flexdrop_check_memory();
}
printk(KERN_INFO "flexdrop thread stopping...\n");
/* do_exit(); */
return 0;
}
static int __init drop_start(void)
{
struct task_struct *task;
printk(KERN_INFO "#########################################################################################\n");
printk(KERN_INFO "############################### COUCOU ###############################\n");
printk(KERN_INFO "#########################################################################################\n");
printk(KERN_INFO "Loading flexdrop module... All your memory are belong to us.\n");
printk(KERN_INFO "Hello world. I will happily free your memory when I have the feeling to do so.\n");
kresolv_init();
task = kthread_create(flexdrop_thread, NULL, "flexdrop");
wake_up_process(task);
gl_flexdrop_task = task;
return 0;
}
static void __exit drop_end(void)
{
if (gl_flexdrop_task)
{
printk(KERN_INFO "flexdrop stop()...\n");
atomic_inc(&flexdrop_wakeup);
wake_up(&flexdrop_waitqueue);
kthread_stop(gl_flexdrop_task);
gl_flexdrop_task = NULL;
printk(KERN_INFO "flexdrop stopped!\n");
}
printk(KERN_INFO "Goodbye Mr. FlexDrop\n\n");
}
module_init(drop_start);
module_exit(drop_end);
#define VERSION "0.1"
MODULE_AUTHOR("Eric Gouyer <folays@folays.net>");
MODULE_DESCRIPTION("Flexible Memory Drop Cache ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
/* MODULE_LICENSE("Proprietary"); */