// SPDX-License-Identifier: GPL-2.0
/*
 * proactive reclamation: monitor access pattern of a given process, find
 * regions that seems not accessed, and proactively page out the regions.
 */

#define pr_fmt(fmt) "damon_sample_prcl: " fmt

#include <linux/damon.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX "damon_sample_prcl."

static int target_pid __read_mostly;
module_param(target_pid, int, 0600);

static int damon_sample_prcl_enable_store(
		const char *val, const struct kernel_param *kp);

static const struct kernel_param_ops enabled_param_ops = {
	.set = damon_sample_prcl_enable_store,
	.get = param_get_bool,
};

static bool enabled __read_mostly;
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_PRCL");

static struct damon_ctx *ctx;
static struct pid *target_pidp;

static int damon_sample_prcl_repeat_call_fn(void *data)
{
	struct damon_ctx *c = data;
	struct damon_target *t;

	damon_for_each_target(t, c) {
		struct damon_region *r;
		unsigned long wss = 0;

		damon_for_each_region(r, t) {
			if (r->nr_accesses > 0)
				wss += r->ar.end - r->ar.start;
		}
		pr_info("wss: %lu\n", wss);
	}
	return 0;
}

static struct damon_call_control repeat_call_control = {
	.fn = damon_sample_prcl_repeat_call_fn,
	.repeat = true,
};

static int damon_sample_prcl_start(void)
{
	struct damon_target *target;
	struct damos *scheme;
	int err;

	pr_info("start\n");

	ctx = damon_new_ctx();
	if (!ctx)
		return -ENOMEM;
	if (damon_select_ops(ctx, DAMON_OPS_VADDR)) {
		damon_destroy_ctx(ctx);
		return -EINVAL;
	}

	target = damon_new_target();
	if (!target) {
		damon_destroy_ctx(ctx);
		return -ENOMEM;
	}
	damon_add_target(ctx, target);
	target_pidp = find_get_pid(target_pid);
	if (!target_pidp) {
		damon_destroy_ctx(ctx);
		return -EINVAL;
	}
	target->pid = target_pidp;

	scheme = damon_new_scheme(
			&(struct damos_access_pattern) {
			.min_sz_region = PAGE_SIZE,
			.max_sz_region = ULONG_MAX,
			.min_nr_accesses = 0,
			.max_nr_accesses = 0,
			.min_age_region = 50,
			.max_age_region = UINT_MAX},
			DAMOS_PAGEOUT,
			0,
			&(struct damos_quota){},
			&(struct damos_watermarks){},
			NUMA_NO_NODE);
	if (!scheme) {
		damon_destroy_ctx(ctx);
		return -ENOMEM;
	}
	damon_set_schemes(ctx, &scheme, 1);

	err = damon_start(&ctx, 1, true);
	if (err)
		return err;

	repeat_call_control.data = ctx;
	return damon_call(ctx, &repeat_call_control);
}

static void damon_sample_prcl_stop(void)
{
	pr_info("stop\n");
	if (ctx) {
		damon_stop(&ctx, 1);
		damon_destroy_ctx(ctx);
	}
}

static bool init_called;

static int damon_sample_prcl_enable_store(
		const char *val, const struct kernel_param *kp)
{
	bool is_enabled = enabled;
	int err;

	err = kstrtobool(val, &enabled);
	if (err)
		return err;

	if (enabled == is_enabled)
		return 0;

	if (enabled) {
		err = damon_sample_prcl_start();
		if (err)
			enabled = false;
		return err;
	}
	damon_sample_prcl_stop();
	return 0;
}

static int __init damon_sample_prcl_init(void)
{
	int err = 0;

	init_called = true;
	if (enabled) {
		err = damon_sample_prcl_start();
		if (err)
			enabled = false;
	}
	return 0;
}

module_init(damon_sample_prcl_init);
