linux/mm/damon/sysfs-schemes.c

// SPDX-License-Identifier: GPL-2.0
/*
 * DAMON sysfs Interface
 *
 * Copyright (c) 2022 SeongJae Park <[email protected]>
 */

#include <linux/slab.h>
#include <linux/numa.h>

#include "sysfs-common.h"

/*
 * scheme region directory
 */

struct damon_sysfs_scheme_region {};

static struct damon_sysfs_scheme_region *damon_sysfs_scheme_region_alloc(
		struct damon_region *region)
{}

static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t end_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t nr_accesses_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t age_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static void damon_sysfs_scheme_region_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_scheme_region_start_attr =;

static struct kobj_attribute damon_sysfs_scheme_region_end_attr =;

static struct kobj_attribute damon_sysfs_scheme_region_nr_accesses_attr =;

static struct kobj_attribute damon_sysfs_scheme_region_age_attr =;

static struct attribute *damon_sysfs_scheme_region_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_scheme_region_ktype =;

/*
 * scheme regions directory
 */

/*
 * enum damos_sysfs_regions_upd_status - Represent DAMOS tried regions update
 *					 status
 * @DAMOS_TRIED_REGIONS_UPD_IDLE:		Waiting for next request.
 * @DAMOS_TRIED_REGIONS_UPD_STARTED:		Update started.
 * @DAMOS_TRIED_REGIONS_UPD_FINISHED:	Update finished.
 *
 * Each DAMON-based operation scheme (&struct damos) has its own apply
 * interval, and we need to expose the scheme tried regions based on only
 * single snapshot.  For this, we keep the tried regions update status for each
 * scheme.  The status becomes 'idle' at the beginning.
 *
 * Once the tried regions update request is received, the request handling
 * start function (damon_sysfs_scheme_update_regions_start()) sets the status
 * of all schemes as 'idle' again, and register ->before_damos_apply()
 * callback.
 *
 * Then, the first followup ->before_damos_apply() callback
 * (damon_sysfs_before_damos_apply()) sets the status 'started'.  The first
 * ->after_sampling() or ->after_aggregation() callback
 *  (damon_sysfs_cmd_request_callback()) after the call is called only after
 *  the scheme is completely applied to the given snapshot.  Hence the callback
 *  knows the situation by showing 'started' status, and sets the status as
 *  'finished'.  Then, damon_sysfs_before_damos_apply() understands the
 *  situation by showing the 'finished' status and do nothing.
 *
 * If DAMOS is not applied to any region due to any reasons including the
 * access pattern, the watermarks, the quotas, and the filters,
 * ->before_damos_apply() will not be called back.  Until the situation is
 * changed, the update will not be finished.  To avoid this,
 * damon_sysfs_after_sampling() set the status as 'finished' if more than two
 * apply intervals of the scheme is passed while the state is 'idle'.
 *
 *  Finally, the tried regions request handling finisher function
 *  (damon_sysfs_schemes_update_regions_stop()) unregisters the callbacks.
 */
enum damos_sysfs_regions_upd_status {};

struct damon_sysfs_scheme_regions {};

static struct damon_sysfs_scheme_regions *
damon_sysfs_scheme_regions_alloc(void)
{}

static ssize_t total_bytes_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static void damon_sysfs_scheme_regions_rm_dirs(
		struct damon_sysfs_scheme_regions *regions)
{}

static void damon_sysfs_scheme_regions_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_scheme_regions_total_bytes_attr =;

static struct attribute *damon_sysfs_scheme_regions_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_scheme_regions_ktype =;

/*
 * schemes/stats directory
 */

struct damon_sysfs_stats {};

static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void)
{}

static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t nr_applied_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t sz_applied_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t qt_exceeds_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static void damon_sysfs_stats_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =;

static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =;

static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =;

static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =;

static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =;

static struct attribute *damon_sysfs_stats_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_stats_ktype =;

/*
 * filter directory
 */

struct damon_sysfs_scheme_filter {};

static struct damon_sysfs_scheme_filter *damon_sysfs_scheme_filter_alloc(void)
{}

/* Should match with enum damos_filter_type */
static const char * const damon_sysfs_scheme_filter_type_strs[] =;

static ssize_t type_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t type_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t matching_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t matching_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t memcg_path_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t memcg_path_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t addr_start_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t addr_start_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t addr_end_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t addr_end_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t damon_target_idx_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t damon_target_idx_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_scheme_filter_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_scheme_filter_type_attr =;

static struct kobj_attribute damon_sysfs_scheme_filter_matching_attr =;

static struct kobj_attribute damon_sysfs_scheme_filter_memcg_path_attr =;

static struct kobj_attribute damon_sysfs_scheme_filter_addr_start_attr =;

static struct kobj_attribute damon_sysfs_scheme_filter_addr_end_attr =;

static struct kobj_attribute damon_sysfs_scheme_filter_damon_target_idx_attr =;

static struct attribute *damon_sysfs_scheme_filter_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_scheme_filter_ktype =;

/*
 * filters directory
 */

struct damon_sysfs_scheme_filters {};

static struct damon_sysfs_scheme_filters *
damon_sysfs_scheme_filters_alloc(void)
{}

static void damon_sysfs_scheme_filters_rm_dirs(
		struct damon_sysfs_scheme_filters *filters)
{}

static int damon_sysfs_scheme_filters_add_dirs(
		struct damon_sysfs_scheme_filters *filters, int nr_filters)
{}

static ssize_t nr_filters_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t nr_filters_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_scheme_filters_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_scheme_filters_nr_attr =;

static struct attribute *damon_sysfs_scheme_filters_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_scheme_filters_ktype =;

/*
 * watermarks directory
 */

struct damon_sysfs_watermarks {};

static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc(
		enum damos_wmark_metric metric, unsigned long interval_us,
		unsigned long high, unsigned long mid, unsigned long low)
{}

/* Should match with enum damos_wmark_metric */
static const char * const damon_sysfs_wmark_metric_strs[] =;

static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t count)
{}

static ssize_t interval_us_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t interval_us_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t high_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t high_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t mid_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t mid_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t low_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t low_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_watermarks_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_watermarks_metric_attr =;

static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =;

static struct kobj_attribute damon_sysfs_watermarks_high_attr =;

static struct kobj_attribute damon_sysfs_watermarks_mid_attr =;

static struct kobj_attribute damon_sysfs_watermarks_low_attr =;

static struct attribute *damon_sysfs_watermarks_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_watermarks_ktype =;

/*
 * quota goal directory
 */

struct damos_sysfs_quota_goal {};

/* This should match with enum damos_action */
static const char * const damos_sysfs_quota_goal_metric_strs[] =;

static struct damos_sysfs_quota_goal *damos_sysfs_quota_goal_alloc(void)
{}

static ssize_t target_metric_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t target_metric_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t target_value_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t target_value_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t current_value_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t current_value_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damos_sysfs_quota_goal_release(struct kobject *kobj)
{}

static struct kobj_attribute damos_sysfs_quota_goal_target_metric_attr =;

static struct kobj_attribute damos_sysfs_quota_goal_target_value_attr =;

static struct kobj_attribute damos_sysfs_quota_goal_current_value_attr =;

static struct attribute *damos_sysfs_quota_goal_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damos_sysfs_quota_goal_ktype =;

/*
 * quota goals directory
 */

struct damos_sysfs_quota_goals {};

static struct damos_sysfs_quota_goals *damos_sysfs_quota_goals_alloc(void)
{}

static void damos_sysfs_quota_goals_rm_dirs(
		struct damos_sysfs_quota_goals *goals)
{}

static int damos_sysfs_quota_goals_add_dirs(
		struct damos_sysfs_quota_goals *goals, int nr_goals)
{}

static ssize_t nr_goals_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t nr_goals_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damos_sysfs_quota_goals_release(struct kobject *kobj)
{}

static struct kobj_attribute damos_sysfs_quota_goals_nr_attr =;

static struct attribute *damos_sysfs_quota_goals_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damos_sysfs_quota_goals_ktype =;

/*
 * scheme/weights directory
 */

struct damon_sysfs_weights {};

static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz,
		unsigned int nr_accesses, unsigned int age)
{}

static ssize_t sz_permil_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t sz_permil_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t nr_accesses_permil_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t nr_accesses_permil_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t age_permil_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t age_permil_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_weights_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_weights_sz_attr =;

static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =;

static struct kobj_attribute damon_sysfs_weights_age_attr =;

static struct attribute *damon_sysfs_weights_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_weights_ktype =;

/*
 * quotas directory
 */

struct damon_sysfs_quotas {};

static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
{}

static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas)
{}

static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas)
{}

static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t count)
{}

static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t bytes_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t reset_interval_ms_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t reset_interval_ms_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t effective_bytes_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static void damon_sysfs_quotas_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_quotas_ms_attr =;

static struct kobj_attribute damon_sysfs_quotas_sz_attr =;

static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =;

static struct kobj_attribute damon_sysfs_quotas_effective_bytes_attr =;

static struct attribute *damon_sysfs_quotas_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_quotas_ktype =;

/*
 * access_pattern directory
 */

struct damon_sysfs_access_pattern {};

static
struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void)
{}

static int damon_sysfs_access_pattern_add_range_dir(
		struct damon_sysfs_access_pattern *access_pattern,
		struct damon_sysfs_ul_range **range_dir_ptr,
		char *name)
{}

static int damon_sysfs_access_pattern_add_dirs(
		struct damon_sysfs_access_pattern *access_pattern)
{}

static void damon_sysfs_access_pattern_rm_dirs(
		struct damon_sysfs_access_pattern *access_pattern)
{}

static void damon_sysfs_access_pattern_release(struct kobject *kobj)
{}

static struct attribute *damon_sysfs_access_pattern_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_access_pattern_ktype =;

/*
 * scheme directory
 */

struct damon_sysfs_scheme {};

/* This should match with enum damos_action */
static const char * const damon_sysfs_damos_action_strs[] =;

static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
		enum damos_action action, unsigned long apply_interval_us)
{}

static int damon_sysfs_scheme_set_access_pattern(
		struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_set_filters(struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_set_tried_regions(
		struct damon_sysfs_scheme *scheme)
{}

static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
{}

static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
{}

static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
{}

static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *attr,
		const char *buf, size_t count)
{}

static ssize_t apply_interval_us_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t apply_interval_us_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static ssize_t target_nid_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t target_nid_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_scheme_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_scheme_action_attr =;

static struct kobj_attribute damon_sysfs_scheme_apply_interval_us_attr =;

static struct kobj_attribute damon_sysfs_scheme_target_nid_attr =;

static struct attribute *damon_sysfs_scheme_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct kobj_type damon_sysfs_scheme_ktype =;

/*
 * schemes directory
 */

struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void)
{}

void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes)
{}

static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes,
		int nr_schemes)
{}

static ssize_t nr_schemes_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}

static ssize_t nr_schemes_store(struct kobject *kobj,
		struct kobj_attribute *attr, const char *buf, size_t count)
{}

static void damon_sysfs_schemes_release(struct kobject *kobj)
{}

static struct kobj_attribute damon_sysfs_schemes_nr_attr =;

static struct attribute *damon_sysfs_schemes_attrs[] =;
ATTRIBUTE_GROUPS();

const struct kobj_type damon_sysfs_schemes_ktype =;

static bool damon_sysfs_memcg_path_eq(struct mem_cgroup *memcg,
		char *memcg_path_buf, char *path)
{}

static int damon_sysfs_memcg_path_to_id(char *memcg_path, unsigned short *id)
{}

static int damon_sysfs_add_scheme_filters(struct damos *scheme,
		struct damon_sysfs_scheme_filters *sysfs_filters)
{}

static int damos_sysfs_add_quota_score(
		struct damos_sysfs_quota_goals *sysfs_goals,
		struct damos_quota *quota)
{}

int damos_sysfs_set_quota_scores(struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx)
{}

void damos_sysfs_update_effective_quotas(
		struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx)
{}

static struct damos *damon_sysfs_mk_scheme(
		struct damon_sysfs_scheme *sysfs_scheme)
{}

int damon_sysfs_add_schemes(struct damon_ctx *ctx,
		struct damon_sysfs_schemes *sysfs_schemes)
{}

void damon_sysfs_schemes_update_stats(
		struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx)
{}

/*
 * damon_sysfs_schemes that need to update its schemes regions dir.  Protected
 * by damon_sysfs_lock
 */
static struct damon_sysfs_schemes *damon_sysfs_schemes_for_damos_callback;
static int damon_sysfs_schemes_region_idx;
static bool damos_regions_upd_total_bytes_only;

/*
 * DAMON callback that called before damos apply.  While this callback is
 * registered, damon_sysfs_lock should be held to ensure the regions
 * directories exist.
 */
static int damon_sysfs_before_damos_apply(struct damon_ctx *ctx,
		struct damon_target *t, struct damon_region *r,
		struct damos *s)
{}

/*
 * DAMON callback that called after each accesses sampling.  While this
 * callback is registered, damon_sysfs_lock should be held to ensure the
 * regions directories exist.
 */
void damos_sysfs_mark_finished_regions_updates(struct damon_ctx *ctx)
{}

/* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
int damon_sysfs_schemes_clear_regions(
		struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx)
{}

static struct damos *damos_sysfs_nth_scheme(int n, struct damon_ctx *ctx)
{}

static void damos_tried_regions_init_upd_status(
		struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx)
{}

/* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
int damon_sysfs_schemes_update_regions_start(
		struct damon_sysfs_schemes *sysfs_schemes,
		struct damon_ctx *ctx, bool total_bytes_only)
{}

bool damos_sysfs_regions_upd_done(void)
{}

/*
 * Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock.  Caller
 * should unlock damon_sysfs_lock which held before
 * damon_sysfs_schemes_update_regions_start()
 */
int damon_sysfs_schemes_update_regions_stop(struct damon_ctx *ctx)
{}