File Index
Files and directories
Sign in
FILE

wsse.c

File preview with syntax highlighting.

linux-6.19.14/samples/damon/wsse.c C
  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
 20static int target_pid __read_mostly;
 21module_param(target_pid, int, 0600);
 22
 23static int damon_sample_wsse_enable_store(
 24		const char *val, const struct kernel_param *kp);
 25
 26static const struct kernel_param_ops enabled_param_ops = {
 27	.set = damon_sample_wsse_enable_store,
 28	.get = param_get_bool,
 29};
 30
 31static bool enabled __read_mostly;
 32module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
 33MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_WSSE");
 34
 35static struct damon_ctx *ctx;
 36static struct pid *target_pidp;
 37
 38static 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
 56static struct damon_call_control repeat_call_control = {
 57	.fn = damon_sample_wsse_repeat_call_fn,
 58	.repeat = true,
 59};
 60
 61static 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
 96static 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
105static int damon_sample_wsse_enable_store(
106		const char *val, const struct kernel_param *kp)
107{
108	bool is_enabled = enabled;
109	int err;
110
111	err = kstrtobool(val, &enabled);
112	if (err)
113		return err;
114
115	if (enabled == is_enabled)
116		return 0;
117
118	if (!damon_initialized())
119		return 0;
120
121	if (enabled) {
122		err = damon_sample_wsse_start();
123		if (err)
124			enabled = false;
125		return err;
126	}
127	damon_sample_wsse_stop();
128	return 0;
129}
130
131static int __init damon_sample_wsse_init(void)
132{
133	int err = 0;
134
135	if (!damon_initialized()) {
136		err = -ENOMEM;
137		if (enabled)
138			enabled = false;
139	}
140
141	if (enabled) {
142		err = damon_sample_wsse_start();
143		if (err)
144			enabled = false;
145	}
146	return err;
147}
148
149module_init(damon_sample_wsse_init);
~/ Read-only file preview.