Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/damon/wsse.c
26288 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* working set size estimation: monitor access pattern of given process and
4
* print estimated working set size (total size of regions that showing some
5
* access).
6
*/
7
8
#define pr_fmt(fmt) "damon_sample_wsse: " fmt
9
10
#include <linux/damon.h>
11
#include <linux/init.h>
12
#include <linux/kernel.h>
13
#include <linux/module.h>
14
15
#ifdef MODULE_PARAM_PREFIX
16
#undef MODULE_PARAM_PREFIX
17
#endif
18
#define MODULE_PARAM_PREFIX "damon_sample_wsse."
19
20
static int target_pid __read_mostly;
21
module_param(target_pid, int, 0600);
22
23
static int damon_sample_wsse_enable_store(
24
const char *val, const struct kernel_param *kp);
25
26
static const struct kernel_param_ops enabled_param_ops = {
27
.set = damon_sample_wsse_enable_store,
28
.get = param_get_bool,
29
};
30
31
static bool enabled __read_mostly;
32
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
33
MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_WSSE");
34
35
static struct damon_ctx *ctx;
36
static struct pid *target_pidp;
37
38
static int damon_sample_wsse_repeat_call_fn(void *data)
39
{
40
struct damon_ctx *c = data;
41
struct damon_target *t;
42
43
damon_for_each_target(t, c) {
44
struct damon_region *r;
45
unsigned long wss = 0;
46
47
damon_for_each_region(r, t) {
48
if (r->nr_accesses > 0)
49
wss += r->ar.end - r->ar.start;
50
}
51
pr_info("wss: %lu\n", wss);
52
}
53
return 0;
54
}
55
56
static struct damon_call_control repeat_call_control = {
57
.fn = damon_sample_wsse_repeat_call_fn,
58
.repeat = true,
59
};
60
61
static int damon_sample_wsse_start(void)
62
{
63
struct damon_target *target;
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
err = damon_start(&ctx, 1, true);
90
if (err)
91
return err;
92
repeat_call_control.data = ctx;
93
return damon_call(ctx, &repeat_call_control);
94
}
95
96
static void damon_sample_wsse_stop(void)
97
{
98
pr_info("stop\n");
99
if (ctx) {
100
damon_stop(&ctx, 1);
101
damon_destroy_ctx(ctx);
102
}
103
}
104
105
static bool init_called;
106
107
static int damon_sample_wsse_enable_store(
108
const char *val, const struct kernel_param *kp)
109
{
110
bool is_enabled = enabled;
111
int err;
112
113
err = kstrtobool(val, &enabled);
114
if (err)
115
return err;
116
117
if (enabled == is_enabled)
118
return 0;
119
120
if (enabled) {
121
err = damon_sample_wsse_start();
122
if (err)
123
enabled = false;
124
return err;
125
}
126
damon_sample_wsse_stop();
127
return 0;
128
}
129
130
static int __init damon_sample_wsse_init(void)
131
{
132
int err = 0;
133
134
init_called = true;
135
if (enabled) {
136
err = damon_sample_wsse_start();
137
if (err)
138
enabled = false;
139
}
140
return err;
141
}
142
143
module_init(damon_sample_wsse_init);
144
145