Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/damon/prcl.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* proactive reclamation: monitor access pattern of a given process, find
4
* regions that seems not accessed, and proactively page out the regions.
5
*/
6
7
#define pr_fmt(fmt) "damon_sample_prcl: " fmt
8
9
#include <linux/damon.h>
10
#include <linux/init.h>
11
#include <linux/kernel.h>
12
#include <linux/module.h>
13
14
#ifdef MODULE_PARAM_PREFIX
15
#undef MODULE_PARAM_PREFIX
16
#endif
17
#define MODULE_PARAM_PREFIX "damon_sample_prcl."
18
19
static int target_pid __read_mostly;
20
module_param(target_pid, int, 0600);
21
22
static int damon_sample_prcl_enable_store(
23
const char *val, const struct kernel_param *kp);
24
25
static const struct kernel_param_ops enabled_param_ops = {
26
.set = damon_sample_prcl_enable_store,
27
.get = param_get_bool,
28
};
29
30
static bool enabled __read_mostly;
31
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
32
MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_PRCL");
33
34
static struct damon_ctx *ctx;
35
static struct pid *target_pidp;
36
37
static int damon_sample_prcl_repeat_call_fn(void *data)
38
{
39
struct damon_ctx *c = data;
40
struct damon_target *t;
41
42
damon_for_each_target(t, c) {
43
struct damon_region *r;
44
unsigned long wss = 0;
45
46
damon_for_each_region(r, t) {
47
if (r->nr_accesses > 0)
48
wss += r->ar.end - r->ar.start;
49
}
50
pr_info("wss: %lu\n", wss);
51
}
52
return 0;
53
}
54
55
static struct damon_call_control repeat_call_control = {
56
.fn = damon_sample_prcl_repeat_call_fn,
57
.repeat = true,
58
};
59
60
static int damon_sample_prcl_start(void)
61
{
62
struct damon_target *target;
63
struct damos *scheme;
64
int err;
65
66
pr_info("start\n");
67
68
ctx = damon_new_ctx();
69
if (!ctx)
70
return -ENOMEM;
71
if (damon_select_ops(ctx, DAMON_OPS_VADDR)) {
72
damon_destroy_ctx(ctx);
73
return -EINVAL;
74
}
75
76
target = damon_new_target();
77
if (!target) {
78
damon_destroy_ctx(ctx);
79
return -ENOMEM;
80
}
81
damon_add_target(ctx, target);
82
target_pidp = find_get_pid(target_pid);
83
if (!target_pidp) {
84
damon_destroy_ctx(ctx);
85
return -EINVAL;
86
}
87
target->pid = target_pidp;
88
89
scheme = damon_new_scheme(
90
&(struct damos_access_pattern) {
91
.min_sz_region = PAGE_SIZE,
92
.max_sz_region = ULONG_MAX,
93
.min_nr_accesses = 0,
94
.max_nr_accesses = 0,
95
.min_age_region = 50,
96
.max_age_region = UINT_MAX},
97
DAMOS_PAGEOUT,
98
0,
99
&(struct damos_quota){},
100
&(struct damos_watermarks){},
101
NUMA_NO_NODE);
102
if (!scheme) {
103
damon_destroy_ctx(ctx);
104
return -ENOMEM;
105
}
106
damon_set_schemes(ctx, &scheme, 1);
107
108
err = damon_start(&ctx, 1, true);
109
if (err)
110
return err;
111
112
repeat_call_control.data = ctx;
113
return damon_call(ctx, &repeat_call_control);
114
}
115
116
static void damon_sample_prcl_stop(void)
117
{
118
pr_info("stop\n");
119
if (ctx) {
120
damon_stop(&ctx, 1);
121
damon_destroy_ctx(ctx);
122
}
123
}
124
125
static bool init_called;
126
127
static int damon_sample_prcl_enable_store(
128
const char *val, const struct kernel_param *kp)
129
{
130
bool is_enabled = enabled;
131
int err;
132
133
err = kstrtobool(val, &enabled);
134
if (err)
135
return err;
136
137
if (enabled == is_enabled)
138
return 0;
139
140
if (enabled) {
141
err = damon_sample_prcl_start();
142
if (err)
143
enabled = false;
144
return err;
145
}
146
damon_sample_prcl_stop();
147
return 0;
148
}
149
150
static int __init damon_sample_prcl_init(void)
151
{
152
int err = 0;
153
154
init_called = true;
155
if (enabled) {
156
err = damon_sample_prcl_start();
157
if (err)
158
enabled = false;
159
}
160
return 0;
161
}
162
163
module_init(damon_sample_prcl_init);
164
165