// SPDX-License-Identifier: GPL-2.0
/*
 * Data Access Monitor
 *
 * Author: SeongJae Park <sj@kernel.org>
 */

#define pr_fmt(fmt) "damon: " fmt

#include <linux/damon.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/string.h>

#define CREATE_TRACE_POINTS
#include <trace/events/damon.h>

#ifdef CONFIG_DAMON_KUNIT_TEST
#undef DAMON_MIN_REGION
#define DAMON_MIN_REGION 1
#endif

static DEFINE_MUTEX(damon_lock);
static int nr_running_ctxs;
static bool running_exclusive_ctxs;

static DEFINE_MUTEX(damon_ops_lock);
static struct damon_operations damon_registered_ops[NR_DAMON_OPS];

static struct kmem_cache *damon_region_cache __ro_after_init;

/* Should be called under damon_ops_lock with id smaller than NR_DAMON_OPS */
static bool __damon_is_registered_ops(enum damon_ops_id id)
{
	struct damon_operations empty_ops = {};

	if (!memcmp(&empty_ops, &damon_registered_ops[id], sizeof(empty_ops)))
		return false;
	return true;
}

/**
 * damon_is_registered_ops() - Check if a given damon_operations is registered.
 * @id:	Id of the damon_operations to check if registered.
 *
 * Return: true if the ops is set, false otherwise.
 */
bool damon_is_registered_ops(enum damon_ops_id id)
{
	bool registered;

	if (id >= NR_DAMON_OPS)
		return false;
	mutex_lock(&damon_ops_lock);
	registered = __damon_is_registered_ops(id);
	mutex_unlock(&damon_ops_lock);
	return registered;
}

/**
 * damon_register_ops() - Register a monitoring operations set to DAMON.
 * @ops:	monitoring operations set to register.
 *
 * This function registers a monitoring operations set of valid &struct
 * damon_operations->id so that others can find and use them later.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_register_ops(struct damon_operations *ops)
{
	int err = 0;

	if (ops->id >= NR_DAMON_OPS)
		return -EINVAL;
	mutex_lock(&damon_ops_lock);
	/* Fail for already registered ops */
	if (__damon_is_registered_ops(ops->id)) {
		err = -EINVAL;
		goto out;
	}
	damon_registered_ops[ops->id] = *ops;
out:
	mutex_unlock(&damon_ops_lock);
	return err;
}

/**
 * damon_select_ops() - Select a monitoring operations to use with the context.
 * @ctx:	monitoring context to use the operations.
 * @id:		id of the registered monitoring operations to select.
 *
 * This function finds registered monitoring operations set of @id and make
 * @ctx to use it.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id)
{
	int err = 0;

	if (id >= NR_DAMON_OPS)
		return -EINVAL;

	mutex_lock(&damon_ops_lock);
	if (!__damon_is_registered_ops(id))
		err = -EINVAL;
	else
		ctx->ops = damon_registered_ops[id];
	mutex_unlock(&damon_ops_lock);
	return err;
}

/*
 * Construct a damon_region struct
 *
 * Returns the pointer to the new struct if success, or NULL otherwise
 */
struct damon_region *damon_new_region(unsigned long start, unsigned long end)
{
	struct damon_region *region;

	region = kmem_cache_alloc(damon_region_cache, GFP_KERNEL);
	if (!region)
		return NULL;

	region->ar.start = start;
	region->ar.end = end;
	region->nr_accesses = 0;
	region->nr_accesses_bp = 0;
	INIT_LIST_HEAD(&region->list);

	region->age = 0;
	region->last_nr_accesses = 0;

	return region;
}

void damon_add_region(struct damon_region *r, struct damon_target *t)
{
	list_add_tail(&r->list, &t->regions_list);
	t->nr_regions++;
}

static void damon_del_region(struct damon_region *r, struct damon_target *t)
{
	list_del(&r->list);
	t->nr_regions--;
}

static void damon_free_region(struct damon_region *r)
{
	kmem_cache_free(damon_region_cache, r);
}

void damon_destroy_region(struct damon_region *r, struct damon_target *t)
{
	damon_del_region(r, t);
	damon_free_region(r);
}

/*
 * Check whether a region is intersecting an address range
 *
 * Returns true if it is.
 */
static bool damon_intersect(struct damon_region *r,
		struct damon_addr_range *re)
{
	return !(r->ar.end <= re->start || re->end <= r->ar.start);
}

/*
 * Fill holes in regions with new regions.
 */
static int damon_fill_regions_holes(struct damon_region *first,
		struct damon_region *last, struct damon_target *t)
{
	struct damon_region *r = first;

	damon_for_each_region_from(r, t) {
		struct damon_region *next, *newr;

		if (r == last)
			break;
		next = damon_next_region(r);
		if (r->ar.end != next->ar.start) {
			newr = damon_new_region(r->ar.end, next->ar.start);
			if (!newr)
				return -ENOMEM;
			damon_insert_region(newr, r, next, t);
		}
	}
	return 0;
}

/*
 * damon_set_regions() - Set regions of a target for given address ranges.
 * @t:		the given target.
 * @ranges:	array of new monitoring target ranges.
 * @nr_ranges:	length of @ranges.
 *
 * This function adds new regions to, or modify existing regions of a
 * monitoring target to fit in specific ranges.
 *
 * Return: 0 if success, or negative error code otherwise.
 */
int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
		unsigned int nr_ranges)
{
	struct damon_region *r, *next;
	unsigned int i;
	int err;

	/* Remove regions which are not in the new ranges */
	damon_for_each_region_safe(r, next, t) {
		for (i = 0; i < nr_ranges; i++) {
			if (damon_intersect(r, &ranges[i]))
				break;
		}
		if (i == nr_ranges)
			damon_destroy_region(r, t);
	}

	r = damon_first_region(t);
	/* Add new regions or resize existing regions to fit in the ranges */
	for (i = 0; i < nr_ranges; i++) {
		struct damon_region *first = NULL, *last, *newr;
		struct damon_addr_range *range;

		range = &ranges[i];
		/* Get the first/last regions intersecting with the range */
		damon_for_each_region_from(r, t) {
			if (damon_intersect(r, range)) {
				if (!first)
					first = r;
				last = r;
			}
			if (r->ar.start >= range->end)
				break;
		}
		if (!first) {
			/* no region intersects with this range */
			newr = damon_new_region(
					ALIGN_DOWN(range->start,
						DAMON_MIN_REGION),
					ALIGN(range->end, DAMON_MIN_REGION));
			if (!newr)
				return -ENOMEM;
			damon_insert_region(newr, damon_prev_region(r), r, t);
		} else {
			/* resize intersecting regions to fit in this range */
			first->ar.start = ALIGN_DOWN(range->start,
					DAMON_MIN_REGION);
			last->ar.end = ALIGN(range->end, DAMON_MIN_REGION);

			/* fill possible holes in the range */
			err = damon_fill_regions_holes(first, last, t);
			if (err)
				return err;
		}
	}
	return 0;
}

struct damos_filter *damos_new_filter(enum damos_filter_type type,
		bool matching)
{
	struct damos_filter *filter;

	filter = kmalloc(sizeof(*filter), GFP_KERNEL);
	if (!filter)
		return NULL;
	filter->type = type;
	filter->matching = matching;
	INIT_LIST_HEAD(&filter->list);
	return filter;
}

void damos_add_filter(struct damos *s, struct damos_filter *f)
{
	list_add_tail(&f->list, &s->filters);
}

static void damos_del_filter(struct damos_filter *f)
{
	list_del(&f->list);
}

static void damos_free_filter(struct damos_filter *f)
{
	kfree(f);
}

void damos_destroy_filter(struct damos_filter *f)
{
	damos_del_filter(f);
	damos_free_filter(f);
}

/* initialize private fields of damos_quota and return the pointer */
static struct damos_quota *damos_quota_init_priv(struct damos_quota *quota)
{
	quota->total_charged_sz = 0;
	quota->total_charged_ns = 0;
	quota->esz = 0;
	quota->charged_sz = 0;
	quota->charged_from = 0;
	quota->charge_target_from = NULL;
	quota->charge_addr_from = 0;
	return quota;
}

struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
			enum damos_action action,
			unsigned long apply_interval_us,
			struct damos_quota *quota,
			struct damos_watermarks *wmarks)
{
	struct damos *scheme;

	scheme = kmalloc(sizeof(*scheme), GFP_KERNEL);
	if (!scheme)
		return NULL;
	scheme->pattern = *pattern;
	scheme->action = action;
	scheme->apply_interval_us = apply_interval_us;
	/*
	 * next_apply_sis will be set when kdamond starts.  While kdamond is
	 * running, it will also updated when it is added to the DAMON context,
	 * or damon_attrs are updated.
	 */
	scheme->next_apply_sis = 0;
	INIT_LIST_HEAD(&scheme->filters);
	scheme->stat = (struct damos_stat){};
	INIT_LIST_HEAD(&scheme->list);

	scheme->quota = *(damos_quota_init_priv(quota));

	scheme->wmarks = *wmarks;
	scheme->wmarks.activated = true;

	return scheme;
}

static void damos_set_next_apply_sis(struct damos *s, struct damon_ctx *ctx)
{
	unsigned long sample_interval = ctx->attrs.sample_interval ?
		ctx->attrs.sample_interval : 1;
	unsigned long apply_interval = s->apply_interval_us ?
		s->apply_interval_us : ctx->attrs.aggr_interval;

	s->next_apply_sis = ctx->passed_sample_intervals +
		apply_interval / sample_interval;
}

void damon_add_scheme(struct damon_ctx *ctx, struct damos *s)
{
	list_add_tail(&s->list, &ctx->schemes);
	damos_set_next_apply_sis(s, ctx);
}

static void damon_del_scheme(struct damos *s)
{
	list_del(&s->list);
}

static void damon_free_scheme(struct damos *s)
{
	kfree(s);
}

void damon_destroy_scheme(struct damos *s)
{
	struct damos_filter *f, *next;

	damos_for_each_filter_safe(f, next, s)
		damos_destroy_filter(f);
	damon_del_scheme(s);
	damon_free_scheme(s);
}

/*
 * Construct a damon_target struct
 *
 * Returns the pointer to the new struct if success, or NULL otherwise
 */
struct damon_target *damon_new_target(void)
{
	struct damon_target *t;

	t = kmalloc(sizeof(*t), GFP_KERNEL);
	if (!t)
		return NULL;

	t->pid = NULL;
	t->nr_regions = 0;
	INIT_LIST_HEAD(&t->regions_list);
	INIT_LIST_HEAD(&t->list);

	return t;
}

void damon_add_target(struct damon_ctx *ctx, struct damon_target *t)
{
	list_add_tail(&t->list, &ctx->adaptive_targets);
}

bool damon_targets_empty(struct damon_ctx *ctx)
{
	return list_empty(&ctx->adaptive_targets);
}

static void damon_del_target(struct damon_target *t)
{
	list_del(&t->list);
}

void damon_free_target(struct damon_target *t)
{
	struct damon_region *r, *next;

	damon_for_each_region_safe(r, next, t)
		damon_free_region(r);
	kfree(t);
}

void damon_destroy_target(struct damon_target *t)
{
	damon_del_target(t);
	damon_free_target(t);
}

unsigned int damon_nr_regions(struct damon_target *t)
{
	return t->nr_regions;
}

struct damon_ctx *damon_new_ctx(void)
{
	struct damon_ctx *ctx;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return NULL;

	init_completion(&ctx->kdamond_started);

	ctx->attrs.sample_interval = 5 * 1000;
	ctx->attrs.aggr_interval = 100 * 1000;
	ctx->attrs.ops_update_interval = 60 * 1000 * 1000;

	ctx->passed_sample_intervals = 0;
	/* These will be set from kdamond_init_intervals_sis() */
	ctx->next_aggregation_sis = 0;
	ctx->next_ops_update_sis = 0;

	mutex_init(&ctx->kdamond_lock);

	ctx->attrs.min_nr_regions = 10;
	ctx->attrs.max_nr_regions = 1000;

	INIT_LIST_HEAD(&ctx->adaptive_targets);
	INIT_LIST_HEAD(&ctx->schemes);

	return ctx;
}

static void damon_destroy_targets(struct damon_ctx *ctx)
{
	struct damon_target *t, *next_t;

	if (ctx->ops.cleanup) {
		ctx->ops.cleanup(ctx);
		return;
	}

	damon_for_each_target_safe(t, next_t, ctx)
		damon_destroy_target(t);
}

void damon_destroy_ctx(struct damon_ctx *ctx)
{
	struct damos *s, *next_s;

	damon_destroy_targets(ctx);

	damon_for_each_scheme_safe(s, next_s, ctx)
		damon_destroy_scheme(s);

	kfree(ctx);
}

static unsigned int damon_age_for_new_attrs(unsigned int age,
		struct damon_attrs *old_attrs, struct damon_attrs *new_attrs)
{
	return age * old_attrs->aggr_interval / new_attrs->aggr_interval;
}

/* convert access ratio in bp (per 10,000) to nr_accesses */
static unsigned int damon_accesses_bp_to_nr_accesses(
		unsigned int accesses_bp, struct damon_attrs *attrs)
{
	return accesses_bp * damon_max_nr_accesses(attrs) / 10000;
}

/* convert nr_accesses to access ratio in bp (per 10,000) */
static unsigned int damon_nr_accesses_to_accesses_bp(
		unsigned int nr_accesses, struct damon_attrs *attrs)
{
	return nr_accesses * 10000 / damon_max_nr_accesses(attrs);
}

static unsigned int damon_nr_accesses_for_new_attrs(unsigned int nr_accesses,
		struct damon_attrs *old_attrs, struct damon_attrs *new_attrs)
{
	return damon_accesses_bp_to_nr_accesses(
			damon_nr_accesses_to_accesses_bp(
				nr_accesses, old_attrs),
			new_attrs);
}

static void damon_update_monitoring_result(struct damon_region *r,
		struct damon_attrs *old_attrs, struct damon_attrs *new_attrs)
{
	r->nr_accesses = damon_nr_accesses_for_new_attrs(r->nr_accesses,
			old_attrs, new_attrs);
	r->nr_accesses_bp = r->nr_accesses * 10000;
	r->age = damon_age_for_new_attrs(r->age, old_attrs, new_attrs);
}

/*
 * region->nr_accesses is the number of sampling intervals in the last
 * aggregation interval that access to the region has found, and region->age is
 * the number of aggregation intervals that its access pattern has maintained.
 * For the reason, the real meaning of the two fields depend on current
 * sampling interval and aggregation interval.  This function updates
 * ->nr_accesses and ->age of given damon_ctx's regions for new damon_attrs.
 */
static void damon_update_monitoring_results(struct damon_ctx *ctx,
		struct damon_attrs *new_attrs)
{
	struct damon_attrs *old_attrs = &ctx->attrs;
	struct damon_target *t;
	struct damon_region *r;

	/* if any interval is zero, simply forgive conversion */
	if (!old_attrs->sample_interval || !old_attrs->aggr_interval ||
			!new_attrs->sample_interval ||
			!new_attrs->aggr_interval)
		return;

	damon_for_each_target(t, ctx)
		damon_for_each_region(r, t)
			damon_update_monitoring_result(
					r, old_attrs, new_attrs);
}

/**
 * damon_set_attrs() - Set attributes for the monitoring.
 * @ctx:		monitoring context
 * @attrs:		monitoring attributes
 *
 * This function should be called while the kdamond is not running, or an
 * access check results aggregation is not ongoing (e.g., from
 * &struct damon_callback->after_aggregation or
 * &struct damon_callback->after_wmarks_check callbacks).
 *
 * Every time interval is in micro-seconds.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs)
{
	unsigned long sample_interval = attrs->sample_interval ?
		attrs->sample_interval : 1;
	struct damos *s;

	if (attrs->min_nr_regions < 3)
		return -EINVAL;
	if (attrs->min_nr_regions > attrs->max_nr_regions)
		return -EINVAL;
	if (attrs->sample_interval > attrs->aggr_interval)
		return -EINVAL;

	ctx->next_aggregation_sis = ctx->passed_sample_intervals +
		attrs->aggr_interval / sample_interval;
	ctx->next_ops_update_sis = ctx->passed_sample_intervals +
		attrs->ops_update_interval / sample_interval;

	damon_update_monitoring_results(ctx, attrs);
	ctx->attrs = *attrs;

	damon_for_each_scheme(s, ctx)
		damos_set_next_apply_sis(s, ctx);

	return 0;
}

/**
 * damon_set_schemes() - Set data access monitoring based operation schemes.
 * @ctx:	monitoring context
 * @schemes:	array of the schemes
 * @nr_schemes:	number of entries in @schemes
 *
 * This function should not be called while the kdamond of the context is
 * running.
 */
void damon_set_schemes(struct damon_ctx *ctx, struct damos **schemes,
			ssize_t nr_schemes)
{
	struct damos *s, *next;
	ssize_t i;

	damon_for_each_scheme_safe(s, next, ctx)
		damon_destroy_scheme(s);
	for (i = 0; i < nr_schemes; i++)
		damon_add_scheme(ctx, schemes[i]);
}

/**
 * damon_nr_running_ctxs() - Return number of currently running contexts.
 */
int damon_nr_running_ctxs(void)
{
	int nr_ctxs;

	mutex_lock(&damon_lock);
	nr_ctxs = nr_running_ctxs;
	mutex_unlock(&damon_lock);

	return nr_ctxs;
}

/* Returns the size upper limit for each monitoring region */
static unsigned long damon_region_sz_limit(struct damon_ctx *ctx)
{
	struct damon_target *t;
	struct damon_region *r;
	unsigned long sz = 0;

	damon_for_each_target(t, ctx) {
		damon_for_each_region(r, t)
			sz += damon_sz_region(r);
	}

	if (ctx->attrs.min_nr_regions)
		sz /= ctx->attrs.min_nr_regions;
	if (sz < DAMON_MIN_REGION)
		sz = DAMON_MIN_REGION;

	return sz;
}

static int kdamond_fn(void *data);

/*
 * __damon_start() - Starts monitoring with given context.
 * @ctx:	monitoring context
 *
 * This function should be called while damon_lock is hold.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int __damon_start(struct damon_ctx *ctx)
{
	int err = -EBUSY;

	mutex_lock(&ctx->kdamond_lock);
	if (!ctx->kdamond) {
		err = 0;
		reinit_completion(&ctx->kdamond_started);
		ctx->kdamond = kthread_run(kdamond_fn, ctx, "kdamond.%d",
				nr_running_ctxs);
		if (IS_ERR(ctx->kdamond)) {
			err = PTR_ERR(ctx->kdamond);
			ctx->kdamond = NULL;
		} else {
			wait_for_completion(&ctx->kdamond_started);
		}
	}
	mutex_unlock(&ctx->kdamond_lock);

	return err;
}

/**
 * damon_start() - Starts the monitorings for a given group of contexts.
 * @ctxs:	an array of the pointers for contexts to start monitoring
 * @nr_ctxs:	size of @ctxs
 * @exclusive:	exclusiveness of this contexts group
 *
 * This function starts a group of monitoring threads for a group of monitoring
 * contexts.  One thread per each context is created and run in parallel.  The
 * caller should handle synchronization between the threads by itself.  If
 * @exclusive is true and a group of threads that created by other
 * 'damon_start()' call is currently running, this function does nothing but
 * returns -EBUSY.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive)
{
	int i;
	int err = 0;

	mutex_lock(&damon_lock);
	if ((exclusive && nr_running_ctxs) ||
			(!exclusive && running_exclusive_ctxs)) {
		mutex_unlock(&damon_lock);
		return -EBUSY;
	}

	for (i = 0; i < nr_ctxs; i++) {
		err = __damon_start(ctxs[i]);
		if (err)
			break;
		nr_running_ctxs++;
	}
	if (exclusive && nr_running_ctxs)
		running_exclusive_ctxs = true;
	mutex_unlock(&damon_lock);

	return err;
}

/*
 * __damon_stop() - Stops monitoring of a given context.
 * @ctx:	monitoring context
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int __damon_stop(struct damon_ctx *ctx)
{
	struct task_struct *tsk;

	mutex_lock(&ctx->kdamond_lock);
	tsk = ctx->kdamond;
	if (tsk) {
		get_task_struct(tsk);
		mutex_unlock(&ctx->kdamond_lock);
		kthread_stop_put(tsk);
		return 0;
	}
	mutex_unlock(&ctx->kdamond_lock);

	return -EPERM;
}

/**
 * damon_stop() - Stops the monitorings for a given group of contexts.
 * @ctxs:	an array of the pointers for contexts to stop monitoring
 * @nr_ctxs:	size of @ctxs
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_stop(struct damon_ctx **ctxs, int nr_ctxs)
{
	int i, err = 0;

	for (i = 0; i < nr_ctxs; i++) {
		/* nr_running_ctxs is decremented in kdamond_fn */
		err = __damon_stop(ctxs[i]);
		if (err)
			break;
	}
	return err;
}

/*
 * Reset the aggregated monitoring results ('nr_accesses' of each region).
 */
static void kdamond_reset_aggregated(struct damon_ctx *c)
{
	struct damon_target *t;
	unsigned int ti = 0;	/* target's index */

	damon_for_each_target(t, c) {
		struct damon_region *r;

		damon_for_each_region(r, t) {
			trace_damon_aggregated(ti, r, damon_nr_regions(t));
			r->last_nr_accesses = r->nr_accesses;
			r->nr_accesses = 0;
		}
		ti++;
	}
}

static void damon_split_region_at(struct damon_target *t,
				  struct damon_region *r, unsigned long sz_r);

static bool __damos_valid_target(struct damon_region *r, struct damos *s)
{
	unsigned long sz;
	unsigned int nr_accesses = r->nr_accesses_bp / 10000;

	sz = damon_sz_region(r);
	return s->pattern.min_sz_region <= sz &&
		sz <= s->pattern.max_sz_region &&
		s->pattern.min_nr_accesses <= nr_accesses &&
		nr_accesses <= s->pattern.max_nr_accesses &&
		s->pattern.min_age_region <= r->age &&
		r->age <= s->pattern.max_age_region;
}

static bool damos_valid_target(struct damon_ctx *c, struct damon_target *t,
		struct damon_region *r, struct damos *s)
{
	bool ret = __damos_valid_target(r, s);

	if (!ret || !s->quota.esz || !c->ops.get_scheme_score)
		return ret;

	return c->ops.get_scheme_score(c, t, r, s) >= s->quota.min_score;
}

/*
 * damos_skip_charged_region() - Check if the given region or starting part of
 * it is already charged for the DAMOS quota.
 * @t:	The target of the region.
 * @rp:	The pointer to the region.
 * @s:	The scheme to be applied.
 *
 * If a quota of a scheme has exceeded in a quota charge window, the scheme's
 * action would applied to only a part of the target access pattern fulfilling
 * regions.  To avoid applying the scheme action to only already applied
 * regions, DAMON skips applying the scheme action to the regions that charged
 * in the previous charge window.
 *
 * This function checks if a given region should be skipped or not for the
 * reason.  If only the starting part of the region has previously charged,
 * this function splits the region into two so that the second one covers the
 * area that not charged in the previous charge widnow and saves the second
 * region in *rp and returns false, so that the caller can apply DAMON action
 * to the second one.
 *
 * Return: true if the region should be entirely skipped, false otherwise.
 */
static bool damos_skip_charged_region(struct damon_target *t,
		struct damon_region **rp, struct damos *s)
{
	struct damon_region *r = *rp;
	struct damos_quota *quota = &s->quota;
	unsigned long sz_to_skip;

	/* Skip previously charged regions */
	if (quota->charge_target_from) {
		if (t != quota->charge_target_from)
			return true;
		if (r == damon_last_region(t)) {
			quota->charge_target_from = NULL;
			quota->charge_addr_from = 0;
			return true;
		}
		if (quota->charge_addr_from &&
				r->ar.end <= quota->charge_addr_from)
			return true;

		if (quota->charge_addr_from && r->ar.start <
				quota->charge_addr_from) {
			sz_to_skip = ALIGN_DOWN(quota->charge_addr_from -
					r->ar.start, DAMON_MIN_REGION);
			if (!sz_to_skip) {
				if (damon_sz_region(r) <= DAMON_MIN_REGION)
					return true;
				sz_to_skip = DAMON_MIN_REGION;
			}
			damon_split_region_at(t, r, sz_to_skip);
			r = damon_next_region(r);
			*rp = r;
		}
		quota->charge_target_from = NULL;
		quota->charge_addr_from = 0;
	}
	return false;
}

static void damos_update_stat(struct damos *s,
		unsigned long sz_tried, unsigned long sz_applied)
{
	s->stat.nr_tried++;
	s->stat.sz_tried += sz_tried;
	if (sz_applied)
		s->stat.nr_applied++;
	s->stat.sz_applied += sz_applied;
}

static bool __damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
		struct damon_region *r, struct damos_filter *filter)
{
	bool matched = false;
	struct damon_target *ti;
	int target_idx = 0;
	unsigned long start, end;

	switch (filter->type) {
	case DAMOS_FILTER_TYPE_TARGET:
		damon_for_each_target(ti, ctx) {
			if (ti == t)
				break;
			target_idx++;
		}
		matched = target_idx == filter->target_idx;
		break;
	case DAMOS_FILTER_TYPE_ADDR:
		start = ALIGN_DOWN(filter->addr_range.start, DAMON_MIN_REGION);
		end = ALIGN_DOWN(filter->addr_range.end, DAMON_MIN_REGION);

		/* inside the range */
		if (start <= r->ar.start && r->ar.end <= end) {
			matched = true;
			break;
		}
		/* outside of the range */
		if (r->ar.end <= start || end <= r->ar.start) {
			matched = false;
			break;
		}
		/* start before the range and overlap */
		if (r->ar.start < start) {
			damon_split_region_at(t, r, start - r->ar.start);
			matched = false;
			break;
		}
		/* start inside the range */
		damon_split_region_at(t, r, end - r->ar.start);
		matched = true;
		break;
	default:
		return false;
	}

	return matched == filter->matching;
}

static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
		struct damon_region *r, struct damos *s)
{
	struct damos_filter *filter;

	damos_for_each_filter(filter, s) {
		if (__damos_filter_out(ctx, t, r, filter))
			return true;
	}
	return false;
}

static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
		struct damon_region *r, struct damos *s)
{
	struct damos_quota *quota = &s->quota;
	unsigned long sz = damon_sz_region(r);
	struct timespec64 begin, end;
	unsigned long sz_applied = 0;
	int err = 0;
	/*
	 * We plan to support multiple context per kdamond, as DAMON sysfs
	 * implies with 'nr_contexts' file.  Nevertheless, only single context
	 * per kdamond is supported for now.  So, we can simply use '0' context
	 * index here.
	 */
	unsigned int cidx = 0;
	struct damos *siter;		/* schemes iterator */
	unsigned int sidx = 0;
	struct damon_target *titer;	/* targets iterator */
	unsigned int tidx = 0;
	bool do_trace = false;

	/* get indices for trace_damos_before_apply() */
	if (trace_damos_before_apply_enabled()) {
		damon_for_each_scheme(siter, c) {
			if (siter == s)
				break;
			sidx++;
		}
		damon_for_each_target(titer, c) {
			if (titer == t)
				break;
			tidx++;
		}
		do_trace = true;
	}

	if (c->ops.apply_scheme) {
		if (quota->esz && quota->charged_sz + sz > quota->esz) {
			sz = ALIGN_DOWN(quota->esz - quota->charged_sz,
					DAMON_MIN_REGION);
			if (!sz)
				goto update_stat;
			damon_split_region_at(t, r, sz);
		}
		if (damos_filter_out(c, t, r, s))
			return;
		ktime_get_coarse_ts64(&begin);
		if (c->callback.before_damos_apply)
			err = c->callback.before_damos_apply(c, t, r, s);
		if (!err) {
			trace_damos_before_apply(cidx, sidx, tidx, r,
					damon_nr_regions(t), do_trace);
			sz_applied = c->ops.apply_scheme(c, t, r, s);
		}
		ktime_get_coarse_ts64(&end);
		quota->total_charged_ns += timespec64_to_ns(&end) -
			timespec64_to_ns(&begin);
		quota->charged_sz += sz;
		if (quota->esz && quota->charged_sz >= quota->esz) {
			quota->charge_target_from = t;
			quota->charge_addr_from = r->ar.end + 1;
		}
	}
	if (s->action != DAMOS_STAT)
		r->age = 0;

update_stat:
	damos_update_stat(s, sz, sz_applied);
}

static void damon_do_apply_schemes(struct damon_ctx *c,
				   struct damon_target *t,
				   struct damon_region *r)
{
	struct damos *s;

	damon_for_each_scheme(s, c) {
		struct damos_quota *quota = &s->quota;

		if (!s->wmarks.activated)
			continue;

		/* Check the quota */
		if (quota->esz && quota->charged_sz >= quota->esz)
			continue;

		if (damos_skip_charged_region(t, &r, s))
			continue;

		if (!damos_valid_target(c, t, r, s))
			continue;

		damos_apply_scheme(c, t, r, s);
	}
}

/*
 * damon_feed_loop_next_input() - get next input to achieve a target score.
 * @last_input	The last input.
 * @score	Current score that made with @last_input.
 *
 * Calculate next input to achieve the target score, based on the last input
 * and current score.  Assuming the input and the score are positively
 * proportional, calculate how much compensation should be added to or
 * subtracted from the last input as a proportion of the last input.  Avoid
 * next input always being zero by setting it non-zero always.  In short form
 * (assuming support of float and signed calculations), the algorithm is as
 * below.
 *
 * next_input = max(last_input * ((goal - current) / goal + 1), 1)
 *
 * For simple implementation, we assume the target score is always 10,000.  The
 * caller should adjust @score for this.
 *
 * Returns next input that assumed to achieve the target score.
 */
static unsigned long damon_feed_loop_next_input(unsigned long last_input,
		unsigned long score)
{
	const unsigned long goal = 10000;
	unsigned long score_goal_diff = max(goal, score) - min(goal, score);
	unsigned long score_goal_diff_bp = score_goal_diff * 10000 / goal;
	unsigned long compensation = last_input * score_goal_diff_bp / 10000;
	/* Set minimum input as 10000 to avoid compensation be zero */
	const unsigned long min_input = 10000;

	if (goal > score)
		return last_input + compensation;
	if (last_input > compensation + min_input)
		return last_input - compensation;
	return min_input;
}

/* Shouldn't be called if quota->ms, quota->sz, and quota->get_score unset */
static void damos_set_effective_quota(struct damos_quota *quota)
{
	unsigned long throughput;
	unsigned long esz;

	if (!quota->ms && !quota->get_score) {
		quota->esz = quota->sz;
		return;
	}

	if (quota->get_score) {
		quota->esz_bp = damon_feed_loop_next_input(
				max(quota->esz_bp, 10000UL),
				quota->get_score(quota->get_score_arg));
		esz = quota->esz_bp / 10000;
	}

	if (quota->ms) {
		if (quota->total_charged_ns)
			throughput = quota->total_charged_sz * 1000000 /
				quota->total_charged_ns;
		else
			throughput = PAGE_SIZE * 1024;
		if (quota->get_score)
			esz = min(throughput * quota->ms, esz);
		else
			esz = throughput * quota->ms;
	}

	if (quota->sz && quota->sz < esz)
		esz = quota->sz;

	quota->esz = esz;
}

static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
{
	struct damos_quota *quota = &s->quota;
	struct damon_target *t;
	struct damon_region *r;
	unsigned long cumulated_sz;
	unsigned int score, max_score = 0;

	if (!quota->ms && !quota->sz && !quota->get_score)
		return;

	/* New charge window starts */
	if (time_after_eq(jiffies, quota->charged_from +
				msecs_to_jiffies(quota->reset_interval))) {
		if (quota->esz && quota->charged_sz >= quota->esz)
			s->stat.qt_exceeds++;
		quota->total_charged_sz += quota->charged_sz;
		quota->charged_from = jiffies;
		quota->charged_sz = 0;
		damos_set_effective_quota(quota);
	}

	if (!c->ops.get_scheme_score)
		return;

	/* Fill up the score histogram */
	memset(quota->histogram, 0, sizeof(quota->histogram));
	damon_for_each_target(t, c) {
		damon_for_each_region(r, t) {
			if (!__damos_valid_target(r, s))
				continue;
			score = c->ops.get_scheme_score(c, t, r, s);
			quota->histogram[score] += damon_sz_region(r);
			if (score > max_score)
				max_score = score;
		}
	}

	/* Set the min score limit */
	for (cumulated_sz = 0, score = max_score; ; score--) {
		cumulated_sz += quota->histogram[score];
		if (cumulated_sz >= quota->esz || !score)
			break;
	}
	quota->min_score = score;
}

static void kdamond_apply_schemes(struct damon_ctx *c)
{
	struct damon_target *t;
	struct damon_region *r, *next_r;
	struct damos *s;
	unsigned long sample_interval = c->attrs.sample_interval ?
		c->attrs.sample_interval : 1;
	bool has_schemes_to_apply = false;

	damon_for_each_scheme(s, c) {
		if (c->passed_sample_intervals != s->next_apply_sis)
			continue;

		s->next_apply_sis +=
			(s->apply_interval_us ? s->apply_interval_us :
			 c->attrs.aggr_interval) / sample_interval;

		if (!s->wmarks.activated)
			continue;

		has_schemes_to_apply = true;

		damos_adjust_quota(c, s);
	}

	if (!has_schemes_to_apply)
		return;

	damon_for_each_target(t, c) {
		damon_for_each_region_safe(r, next_r, t)
			damon_do_apply_schemes(c, t, r);
	}
}

/*
 * Merge two adjacent regions into one region
 */
static void damon_merge_two_regions(struct damon_target *t,
		struct damon_region *l, struct damon_region *r)
{
	unsigned long sz_l = damon_sz_region(l), sz_r = damon_sz_region(r);

	l->nr_accesses = (l->nr_accesses * sz_l + r->nr_accesses * sz_r) /
			(sz_l + sz_r);
	l->nr_accesses_bp = l->nr_accesses * 10000;
	l->age = (l->age * sz_l + r->age * sz_r) / (sz_l + sz_r);
	l->ar.end = r->ar.end;
	damon_destroy_region(r, t);
}

/*
 * Merge adjacent regions having similar access frequencies
 *
 * t		target affected by this merge operation
 * thres	'->nr_accesses' diff threshold for the merge
 * sz_limit	size upper limit of each region
 */
static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
				   unsigned long sz_limit)
{
	struct damon_region *r, *prev = NULL, *next;

	damon_for_each_region_safe(r, next, t) {
		if (abs(r->nr_accesses - r->last_nr_accesses) > thres)
			r->age = 0;
		else
			r->age++;

		if (prev && prev->ar.end == r->ar.start &&
		    abs(prev->nr_accesses - r->nr_accesses) <= thres &&
		    damon_sz_region(prev) + damon_sz_region(r) <= sz_limit)
			damon_merge_two_regions(t, prev, r);
		else
			prev = r;
	}
}

/*
 * Merge adjacent regions having similar access frequencies
 *
 * threshold	'->nr_accesses' diff threshold for the merge
 * sz_limit	size upper limit of each region
 *
 * This function merges monitoring target regions which are adjacent and their
 * access frequencies are similar.  This is for minimizing the monitoring
 * overhead under the dynamically changeable access pattern.  If a merge was
 * unnecessarily made, later 'kdamond_split_regions()' will revert it.
 */
static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,
				  unsigned long sz_limit)
{
	struct damon_target *t;

	damon_for_each_target(t, c)
		damon_merge_regions_of(t, threshold, sz_limit);
}

/*
 * Split a region in two
 *
 * r		the region to be split
 * sz_r		size of the first sub-region that will be made
 */
static void damon_split_region_at(struct damon_target *t,
				  struct damon_region *r, unsigned long sz_r)
{
	struct damon_region *new;

	new = damon_new_region(r->ar.start + sz_r, r->ar.end);
	if (!new)
		return;

	r->ar.end = new->ar.start;

	new->age = r->age;
	new->last_nr_accesses = r->last_nr_accesses;
	new->nr_accesses_bp = r->nr_accesses_bp;
	new->nr_accesses = r->nr_accesses;

	damon_insert_region(new, r, damon_next_region(r), t);
}

/* Split every region in the given target into 'nr_subs' regions */
static void damon_split_regions_of(struct damon_target *t, int nr_subs)
{
	struct damon_region *r, *next;
	unsigned long sz_region, sz_sub = 0;
	int i;

	damon_for_each_region_safe(r, next, t) {
		sz_region = damon_sz_region(r);

		for (i = 0; i < nr_subs - 1 &&
				sz_region > 2 * DAMON_MIN_REGION; i++) {
			/*
			 * Randomly select size of left sub-region to be at
			 * least 10 percent and at most 90% of original region
			 */
			sz_sub = ALIGN_DOWN(damon_rand(1, 10) *
					sz_region / 10, DAMON_MIN_REGION);
			/* Do not allow blank region */
			if (sz_sub == 0 || sz_sub >= sz_region)
				continue;

			damon_split_region_at(t, r, sz_sub);
			sz_region = sz_sub;
		}
	}
}

/*
 * Split every target region into randomly-sized small regions
 *
 * This function splits every target region into random-sized small regions if
 * current total number of the regions is equal or smaller than half of the
 * user-specified maximum number of regions.  This is for maximizing the
 * monitoring accuracy under the dynamically changeable access patterns.  If a
 * split was unnecessarily made, later 'kdamond_merge_regions()' will revert
 * it.
 */
static void kdamond_split_regions(struct damon_ctx *ctx)
{
	struct damon_target *t;
	unsigned int nr_regions = 0;
	static unsigned int last_nr_regions;
	int nr_subregions = 2;

	damon_for_each_target(t, ctx)
		nr_regions += damon_nr_regions(t);

	if (nr_regions > ctx->attrs.max_nr_regions / 2)
		return;

	/* Maybe the middle of the region has different access frequency */
	if (last_nr_regions == nr_regions &&
			nr_regions < ctx->attrs.max_nr_regions / 3)
		nr_subregions = 3;

	damon_for_each_target(t, ctx)
		damon_split_regions_of(t, nr_subregions);

	last_nr_regions = nr_regions;
}

/*
 * Check whether current monitoring should be stopped
 *
 * The monitoring is stopped when either the user requested to stop, or all
 * monitoring targets are invalid.
 *
 * Returns true if need to stop current monitoring.
 */
static bool kdamond_need_stop(struct damon_ctx *ctx)
{
	struct damon_target *t;

	if (kthread_should_stop())
		return true;

	if (!ctx->ops.target_valid)
		return false;

	damon_for_each_target(t, ctx) {
		if (ctx->ops.target_valid(t))
			return false;
	}

	return true;
}

static unsigned long damos_wmark_metric_value(enum damos_wmark_metric metric)
{
	switch (metric) {
	case DAMOS_WMARK_FREE_MEM_RATE:
		return global_zone_page_state(NR_FREE_PAGES) * 1000 /
		       totalram_pages();
	default:
		break;
	}
	return -EINVAL;
}

/*
 * Returns zero if the scheme is active.  Else, returns time to wait for next
 * watermark check in micro-seconds.
 */
static unsigned long damos_wmark_wait_us(struct damos *scheme)
{
	unsigned long metric;

	if (scheme->wmarks.metric == DAMOS_WMARK_NONE)
		return 0;

	metric = damos_wmark_metric_value(scheme->wmarks.metric);
	/* higher than high watermark or lower than low watermark */
	if (metric > scheme->wmarks.high || scheme->wmarks.low > metric) {
		if (scheme->wmarks.activated)
			pr_debug("deactivate a scheme (%d) for %s wmark\n",
					scheme->action,
					metric > scheme->wmarks.high ?
					"high" : "low");
		scheme->wmarks.activated = false;
		return scheme->wmarks.interval;
	}

	/* inactive and higher than middle watermark */
	if ((scheme->wmarks.high >= metric && metric >= scheme->wmarks.mid) &&
			!scheme->wmarks.activated)
		return scheme->wmarks.interval;

	if (!scheme->wmarks.activated)
		pr_debug("activate a scheme (%d)\n", scheme->action);
	scheme->wmarks.activated = true;
	return 0;
}

static void kdamond_usleep(unsigned long usecs)
{
	/* See Documentation/timers/timers-howto.rst for the thresholds */
	if (usecs > 20 * USEC_PER_MSEC)
		schedule_timeout_idle(usecs_to_jiffies(usecs));
	else
		usleep_idle_range(usecs, usecs + 1);
}

/* Returns negative error code if it's not activated but should return */
static int kdamond_wait_activation(struct damon_ctx *ctx)
{
	struct damos *s;
	unsigned long wait_time;
	unsigned long min_wait_time = 0;
	bool init_wait_time = false;

	while (!kdamond_need_stop(ctx)) {
		damon_for_each_scheme(s, ctx) {
			wait_time = damos_wmark_wait_us(s);
			if (!init_wait_time || wait_time < min_wait_time) {
				init_wait_time = true;
				min_wait_time = wait_time;
			}
		}
		if (!min_wait_time)
			return 0;

		kdamond_usleep(min_wait_time);

		if (ctx->callback.after_wmarks_check &&
				ctx->callback.after_wmarks_check(ctx))
			break;
	}
	return -EBUSY;
}

static void kdamond_init_intervals_sis(struct damon_ctx *ctx)
{
	unsigned long sample_interval = ctx->attrs.sample_interval ?
		ctx->attrs.sample_interval : 1;
	unsigned long apply_interval;
	struct damos *scheme;

	ctx->passed_sample_intervals = 0;
	ctx->next_aggregation_sis = ctx->attrs.aggr_interval / sample_interval;
	ctx->next_ops_update_sis = ctx->attrs.ops_update_interval /
		sample_interval;

	damon_for_each_scheme(scheme, ctx) {
		apply_interval = scheme->apply_interval_us ?
			scheme->apply_interval_us : ctx->attrs.aggr_interval;
		scheme->next_apply_sis = apply_interval / sample_interval;
	}
}

/*
 * The monitoring daemon that runs as a kernel thread
 */
static int kdamond_fn(void *data)
{
	struct damon_ctx *ctx = data;
	struct damon_target *t;
	struct damon_region *r, *next;
	unsigned int max_nr_accesses = 0;
	unsigned long sz_limit = 0;

	pr_debug("kdamond (%d) starts\n", current->pid);

	complete(&ctx->kdamond_started);
	kdamond_init_intervals_sis(ctx);

	if (ctx->ops.init)
		ctx->ops.init(ctx);
	if (ctx->callback.before_start && ctx->callback.before_start(ctx))
		goto done;

	sz_limit = damon_region_sz_limit(ctx);

	while (!kdamond_need_stop(ctx)) {
		/*
		 * ctx->attrs and ctx->next_{aggregation,ops_update}_sis could
		 * be changed from after_wmarks_check() or after_aggregation()
		 * callbacks.  Read the values here, and use those for this
		 * iteration.  That is, damon_set_attrs() updated new values
		 * are respected from next iteration.
		 */
		unsigned long next_aggregation_sis = ctx->next_aggregation_sis;
		unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
		unsigned long sample_interval = ctx->attrs.sample_interval;

		if (kdamond_wait_activation(ctx))
			break;

		if (ctx->ops.prepare_access_checks)
			ctx->ops.prepare_access_checks(ctx);
		if (ctx->callback.after_sampling &&
				ctx->callback.after_sampling(ctx))
			break;

		kdamond_usleep(sample_interval);
		ctx->passed_sample_intervals++;

		if (ctx->ops.check_accesses)
			max_nr_accesses = ctx->ops.check_accesses(ctx);

		if (ctx->passed_sample_intervals == next_aggregation_sis) {
			kdamond_merge_regions(ctx,
					max_nr_accesses / 10,
					sz_limit);
			if (ctx->callback.after_aggregation &&
					ctx->callback.after_aggregation(ctx))
				break;
		}

		/*
		 * do kdamond_apply_schemes() after kdamond_merge_regions() if
		 * possible, to reduce overhead
		 */
		if (!list_empty(&ctx->schemes))
			kdamond_apply_schemes(ctx);

		sample_interval = ctx->attrs.sample_interval ?
			ctx->attrs.sample_interval : 1;
		if (ctx->passed_sample_intervals == next_aggregation_sis) {
			ctx->next_aggregation_sis = next_aggregation_sis +
				ctx->attrs.aggr_interval / sample_interval;

			kdamond_reset_aggregated(ctx);
			kdamond_split_regions(ctx);
			if (ctx->ops.reset_aggregated)
				ctx->ops.reset_aggregated(ctx);
		}

		if (ctx->passed_sample_intervals == next_ops_update_sis) {
			ctx->next_ops_update_sis = next_ops_update_sis +
				ctx->attrs.ops_update_interval /
				sample_interval;
			if (ctx->ops.update)
				ctx->ops.update(ctx);
			sz_limit = damon_region_sz_limit(ctx);
		}
	}
done:
	damon_for_each_target(t, ctx) {
		damon_for_each_region_safe(r, next, t)
			damon_destroy_region(r, t);
	}

	if (ctx->callback.before_terminate)
		ctx->callback.before_terminate(ctx);
	if (ctx->ops.cleanup)
		ctx->ops.cleanup(ctx);

	pr_debug("kdamond (%d) finishes\n", current->pid);
	mutex_lock(&ctx->kdamond_lock);
	ctx->kdamond = NULL;
	mutex_unlock(&ctx->kdamond_lock);

	mutex_lock(&damon_lock);
	nr_running_ctxs--;
	if (!nr_running_ctxs && running_exclusive_ctxs)
		running_exclusive_ctxs = false;
	mutex_unlock(&damon_lock);

	return 0;
}

/*
 * struct damon_system_ram_region - System RAM resource address region of
 *				    [@start, @end).
 * @start:	Start address of the region (inclusive).
 * @end:	End address of the region (exclusive).
 */
struct damon_system_ram_region {
	unsigned long start;
	unsigned long end;
};

static int walk_system_ram(struct resource *res, void *arg)
{
	struct damon_system_ram_region *a = arg;

	if (a->end - a->start < resource_size(res)) {
		a->start = res->start;
		a->end = res->end;
	}
	return 0;
}

/*
 * Find biggest 'System RAM' resource and store its start and end address in
 * @start and @end, respectively.  If no System RAM is found, returns false.
 */
static bool damon_find_biggest_system_ram(unsigned long *start,
						unsigned long *end)

{
	struct damon_system_ram_region arg = {};

	walk_system_ram_res(0, ULONG_MAX, &arg, walk_system_ram);
	if (arg.end <= arg.start)
		return false;

	*start = arg.start;
	*end = arg.end;
	return true;
}

/**
 * damon_set_region_biggest_system_ram_default() - Set the region of the given
 * monitoring target as requested, or biggest 'System RAM'.
 * @t:		The monitoring target to set the region.
 * @start:	The pointer to the start address of the region.
 * @end:	The pointer to the end address of the region.
 *
 * This function sets the region of @t as requested by @start and @end.  If the
 * values of @start and @end are zero, however, this function finds the biggest
 * 'System RAM' resource and sets the region to cover the resource.  In the
 * latter case, this function saves the start and end addresses of the resource
 * in @start and @end, respectively.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int damon_set_region_biggest_system_ram_default(struct damon_target *t,
			unsigned long *start, unsigned long *end)
{
	struct damon_addr_range addr_range;

	if (*start > *end)
		return -EINVAL;

	if (!*start && !*end &&
		!damon_find_biggest_system_ram(start, end))
		return -EINVAL;

	addr_range.start = *start;
	addr_range.end = *end;
	return damon_set_regions(t, &addr_range, 1);
}

/*
 * damon_moving_sum() - Calculate an inferred moving sum value.
 * @mvsum:	Inferred sum of the last @len_window values.
 * @nomvsum:	Non-moving sum of the last discrete @len_window window values.
 * @len_window:	The number of last values to take care of.
 * @new_value:	New value that will be added to the pseudo moving sum.
 *
 * Moving sum (moving average * window size) is good for handling noise, but
 * the cost of keeping past values can be high for arbitrary window size.  This
 * function implements a lightweight pseudo moving sum function that doesn't
 * keep the past window values.
 *
 * It simply assumes there was no noise in the past, and get the no-noise
 * assumed past value to drop from @nomvsum and @len_window.  @nomvsum is a
 * non-moving sum of the last window.  For example, if @len_window is 10 and we
 * have 25 values, @nomvsum is the sum of the 11th to 20th values of the 25
 * values.  Hence, this function simply drops @nomvsum / @len_window from
 * given @mvsum and add @new_value.
 *
 * For example, if @len_window is 10 and @nomvsum is 50, the last 10 values for
 * the last window could be vary, e.g., 0, 10, 0, 10, 0, 10, 0, 0, 0, 20.  For
 * calculating next moving sum with a new value, we should drop 0 from 50 and
 * add the new value.  However, this function assumes it got value 5 for each
 * of the last ten times.  Based on the assumption, when the next value is
 * measured, it drops the assumed past value, 5 from the current sum, and add
 * the new value to get the updated pseduo-moving average.
 *
 * This means the value could have errors, but the errors will be disappeared
 * for every @len_window aligned calls.  For example, if @len_window is 10, the
 * pseudo moving sum with 11th value to 19th value would have an error.  But
 * the sum with 20th value will not have the error.
 *
 * Return: Pseudo-moving average after getting the @new_value.
 */
static unsigned int damon_moving_sum(unsigned int mvsum, unsigned int nomvsum,
		unsigned int len_window, unsigned int new_value)
{
	return mvsum - nomvsum / len_window + new_value;
}

/**
 * damon_update_region_access_rate() - Update the access rate of a region.
 * @r:		The DAMON region to update for its access check result.
 * @accessed:	Whether the region has accessed during last sampling interval.
 * @attrs:	The damon_attrs of the DAMON context.
 *
 * Update the access rate of a region with the region's last sampling interval
 * access check result.
 *
 * Usually this will be called by &damon_operations->check_accesses callback.
 */
void damon_update_region_access_rate(struct damon_region *r, bool accessed,
		struct damon_attrs *attrs)
{
	unsigned int len_window = 1;

	/*
	 * sample_interval can be zero, but cannot be larger than
	 * aggr_interval, owing to validation of damon_set_attrs().
	 */
	if (attrs->sample_interval)
		len_window = damon_max_nr_accesses(attrs);
	r->nr_accesses_bp = damon_moving_sum(r->nr_accesses_bp,
			r->last_nr_accesses * 10000, len_window,
			accessed ? 10000 : 0);

	if (accessed)
		r->nr_accesses++;
}

static int __init damon_init(void)
{
	damon_region_cache = KMEM_CACHE(damon_region, 0);
	if (unlikely(!damon_region_cache)) {
		pr_err("creating damon_region_cache fails\n");
		return -ENOMEM;
	}

	return 0;
}

subsys_initcall(damon_init);

#include "core-test.h"
