18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * mm/zswapd_control.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/memcontrol.h>
98c2ecf20Sopenharmony_ci#include <linux/types.h>
108c2ecf20Sopenharmony_ci#include <linux/cgroup-defs.h>
118c2ecf20Sopenharmony_ci#include <linux/cgroup.h>
128c2ecf20Sopenharmony_ci#include <linux/memcg_policy.h>
138c2ecf20Sopenharmony_ci#include <linux/zswapd.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include "zswapd_internal.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define ANON_REFAULT_SNAPSHOT_MIN_INTERVAL 200
188c2ecf20Sopenharmony_ci#define AREA_ANON_REFAULT_THRESHOLD 22000
198c2ecf20Sopenharmony_ci#define EMPTY_ROUND_CHECK_THRESHOLD 10
208c2ecf20Sopenharmony_ci#define EMPTY_ROUND_SKIP_INTERVAL 20
218c2ecf20Sopenharmony_ci#define ZSWAPD_MAX_LEVEL_NUM 10
228c2ecf20Sopenharmony_ci#define MAX_SKIP_INTERVAL 1000
238c2ecf20Sopenharmony_ci#define MAX_RECLAIM_SIZE 100
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define INACTIVE_FILE_RATIO 90
268c2ecf20Sopenharmony_ci#define ACTIVE_FILE_RATIO 70
278c2ecf20Sopenharmony_ci#define COMPRESS_RATIO 30
288c2ecf20Sopenharmony_ci#define ZRAM_WM_RATIO 0
298c2ecf20Sopenharmony_ci#define MAX_RATIO 100
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define CHECK_BUFFER_VALID(var1, var2) (((var2) != 0) && ((var1) > (var2)))
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistruct zswapd_param {
348c2ecf20Sopenharmony_ci	unsigned int min_score;
358c2ecf20Sopenharmony_ci	unsigned int max_score;
368c2ecf20Sopenharmony_ci	unsigned int ub_mem2zram_ratio;
378c2ecf20Sopenharmony_ci	unsigned int ub_zram2ufs_ratio;
388c2ecf20Sopenharmony_ci	unsigned int refault_threshold;
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic struct zswapd_param zswap_param[ZSWAPD_MAX_LEVEL_NUM];
428c2ecf20Sopenharmony_cistruct eventfd_ctx *zswapd_press_efd[LEVEL_COUNT];
438c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(pressure_event_lock);
448c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(reclaim_para_lock);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ciatomic_t avail_buffers = ATOMIC_INIT(0);
478c2ecf20Sopenharmony_ciatomic_t min_avail_buffers = ATOMIC_INIT(0);
488c2ecf20Sopenharmony_ciatomic_t high_avail_buffers = ATOMIC_INIT(0);
498c2ecf20Sopenharmony_ciatomic_t max_reclaim_size = ATOMIC_INIT(MAX_RECLAIM_SIZE);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciatomic_t inactive_file_ratio = ATOMIC_INIT(INACTIVE_FILE_RATIO);
528c2ecf20Sopenharmony_ciatomic_t active_file_ratio = ATOMIC_INIT(ACTIVE_FILE_RATIO);
538c2ecf20Sopenharmony_ciatomic_t zram_wm_ratio = ATOMIC_INIT(ZRAM_WM_RATIO);
548c2ecf20Sopenharmony_ciatomic_t compress_ratio = ATOMIC_INIT(COMPRESS_RATIO);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciatomic64_t zram_critical_threshold = ATOMIC_LONG_INIT(0);
578c2ecf20Sopenharmony_ciatomic64_t free_swap_threshold = ATOMIC_LONG_INIT(0);
588c2ecf20Sopenharmony_ciatomic64_t area_anon_refault_threshold = ATOMIC_LONG_INIT(AREA_ANON_REFAULT_THRESHOLD);
598c2ecf20Sopenharmony_ciatomic64_t anon_refault_snapshot_min_interval =
608c2ecf20Sopenharmony_ci	ATOMIC_LONG_INIT(ANON_REFAULT_SNAPSHOT_MIN_INTERVAL);
618c2ecf20Sopenharmony_ciatomic64_t empty_round_skip_interval = ATOMIC_LONG_INIT(EMPTY_ROUND_SKIP_INTERVAL);
628c2ecf20Sopenharmony_ciatomic64_t max_skip_interval = ATOMIC_LONG_INIT(MAX_SKIP_INTERVAL);
638c2ecf20Sopenharmony_ciatomic64_t empty_round_check_threshold = ATOMIC_LONG_INIT(EMPTY_ROUND_CHECK_THRESHOLD);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ciinline unsigned int get_zram_wm_ratio(void)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	return atomic_read(&zram_wm_ratio);
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciinline unsigned int get_compress_ratio(void)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	return atomic_read(&compress_ratio);
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ciinline unsigned int get_inactive_file_ratio(void)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	return atomic_read(&inactive_file_ratio);
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciinline unsigned int get_active_file_ratio(void)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	return atomic_read(&active_file_ratio);
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciinline unsigned int get_avail_buffers(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	return atomic_read(&avail_buffers);
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ciinline unsigned int get_min_avail_buffers(void)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	return atomic_read(&min_avail_buffers);
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ciinline unsigned int get_high_avail_buffers(void)
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci	return atomic_read(&high_avail_buffers);
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ciinline unsigned int get_zswapd_max_reclaim_size(void)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	return atomic_read(&max_reclaim_size);
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciinline unsigned long long get_free_swap_threshold(void)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return atomic64_read(&free_swap_threshold);
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ciinline unsigned long long get_area_anon_refault_threshold(void)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	return atomic64_read(&area_anon_refault_threshold);
1138c2ecf20Sopenharmony_ci}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ciinline unsigned long long get_anon_refault_snapshot_min_interval(void)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	return atomic64_read(&anon_refault_snapshot_min_interval);
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciinline unsigned long long get_empty_round_skip_interval(void)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	return atomic64_read(&empty_round_skip_interval);
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ciinline unsigned long long get_max_skip_interval(void)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	return atomic64_read(&max_skip_interval);
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ciinline unsigned long long get_empty_round_check_threshold(void)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	return atomic64_read(&empty_round_check_threshold);
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ciinline unsigned long long get_zram_critical_threshold(void)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	return atomic64_read(&zram_critical_threshold);
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic ssize_t avail_buffers_params_write(struct kernfs_open_file *of,
1418c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	unsigned long long threshold;
1448c2ecf20Sopenharmony_ci	unsigned int high_buffers;
1458c2ecf20Sopenharmony_ci	unsigned int min_buffers;
1468c2ecf20Sopenharmony_ci	unsigned int buffers;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	buf = strstrip(buf);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	if (sscanf(buf, "%u %u %u %llu", &buffers, &min_buffers, &high_buffers, &threshold) != 4)
1518c2ecf20Sopenharmony_ci		return -EINVAL;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	if (CHECK_BUFFER_VALID(min_buffers, buffers) ||
1548c2ecf20Sopenharmony_ci	    CHECK_BUFFER_VALID(min_buffers, high_buffers) ||
1558c2ecf20Sopenharmony_ci	    CHECK_BUFFER_VALID(buffers, high_buffers))
1568c2ecf20Sopenharmony_ci		return -EINVAL;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	atomic_set(&avail_buffers, buffers);
1598c2ecf20Sopenharmony_ci	atomic_set(&min_avail_buffers, min_buffers);
1608c2ecf20Sopenharmony_ci	atomic_set(&high_avail_buffers, high_buffers);
1618c2ecf20Sopenharmony_ci	atomic64_set(&free_swap_threshold, (threshold * (SZ_1M / PAGE_SIZE)));
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	if (atomic_read(&min_avail_buffers) == 0)
1648c2ecf20Sopenharmony_ci		set_snapshotd_init_flag(0);
1658c2ecf20Sopenharmony_ci	else
1668c2ecf20Sopenharmony_ci		set_snapshotd_init_flag(1);
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	wake_all_zswapd();
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	return nbytes;
1718c2ecf20Sopenharmony_ci}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_cistatic ssize_t zswapd_max_reclaim_size_write(struct kernfs_open_file *of,
1748c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	u32 max;
1778c2ecf20Sopenharmony_ci	int ret;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	buf = strstrip(buf);
1808c2ecf20Sopenharmony_ci	ret = kstrtouint(buf, 10, &max);
1818c2ecf20Sopenharmony_ci	if (ret)
1828c2ecf20Sopenharmony_ci		return -EINVAL;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	atomic_set(&max_reclaim_size, max);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	return nbytes;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistatic ssize_t buffers_ratio_params_write(struct kernfs_open_file *of,
1908c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	unsigned int inactive;
1938c2ecf20Sopenharmony_ci	unsigned int active;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	buf = strstrip(buf);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	if (sscanf(buf, "%u %u", &inactive, &active) != 2)
1988c2ecf20Sopenharmony_ci		return -EINVAL;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	if (inactive > MAX_RATIO || active > MAX_RATIO)
2018c2ecf20Sopenharmony_ci		return -EINVAL;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	atomic_set(&inactive_file_ratio, inactive);
2048c2ecf20Sopenharmony_ci	atomic_set(&active_file_ratio, active);
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	return nbytes;
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic int area_anon_refault_threshold_write(struct cgroup_subsys_state *css,
2108c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2118c2ecf20Sopenharmony_ci{
2128c2ecf20Sopenharmony_ci	atomic64_set(&area_anon_refault_threshold, val);
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	return 0;
2158c2ecf20Sopenharmony_ci}
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic int empty_round_skip_interval_write(struct cgroup_subsys_state *css,
2188c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2198c2ecf20Sopenharmony_ci{
2208c2ecf20Sopenharmony_ci	atomic64_set(&empty_round_skip_interval, val);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	return 0;
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic int max_skip_interval_write(struct cgroup_subsys_state *css,
2268c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	atomic64_set(&max_skip_interval, val);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	return 0;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_cistatic int empty_round_check_threshold_write(struct cgroup_subsys_state *css,
2348c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	atomic64_set(&empty_round_check_threshold, val);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	return 0;
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_cistatic int anon_refault_snapshot_min_interval_write(struct cgroup_subsys_state *css,
2428c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2438c2ecf20Sopenharmony_ci{
2448c2ecf20Sopenharmony_ci	atomic64_set(&anon_refault_snapshot_min_interval, val);
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	return 0;
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_cistatic int zram_critical_thres_write(struct cgroup_subsys_state *css,
2508c2ecf20Sopenharmony_ci				struct cftype *cft, u64 val)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	atomic64_set(&zram_critical_threshold, val);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	return 0;
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic ssize_t zswapd_pressure_event_control(struct kernfs_open_file *of,
2588c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
2598c2ecf20Sopenharmony_ci{
2608c2ecf20Sopenharmony_ci	unsigned int level;
2618c2ecf20Sopenharmony_ci	unsigned int efd;
2628c2ecf20Sopenharmony_ci	struct fd efile;
2638c2ecf20Sopenharmony_ci	int ret;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	buf = strstrip(buf);
2668c2ecf20Sopenharmony_ci	if (sscanf(buf, "%u %u", &efd, &level) != 2)
2678c2ecf20Sopenharmony_ci		return -EINVAL;
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	if (level >= LEVEL_COUNT)
2708c2ecf20Sopenharmony_ci		return -EINVAL;
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	mutex_lock(&pressure_event_lock);
2738c2ecf20Sopenharmony_ci	efile = fdget(efd);
2748c2ecf20Sopenharmony_ci	if (!efile.file) {
2758c2ecf20Sopenharmony_ci		ret = -EBADF;
2768c2ecf20Sopenharmony_ci		goto out;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	zswapd_press_efd[level] = eventfd_ctx_fileget(efile.file);
2808c2ecf20Sopenharmony_ci	if (IS_ERR(zswapd_press_efd[level])) {
2818c2ecf20Sopenharmony_ci		ret = PTR_ERR(zswapd_press_efd[level]);
2828c2ecf20Sopenharmony_ci		goto out_put_efile;
2838c2ecf20Sopenharmony_ci	}
2848c2ecf20Sopenharmony_ci	fdput(efile);
2858c2ecf20Sopenharmony_ci	mutex_unlock(&pressure_event_lock);
2868c2ecf20Sopenharmony_ci	return nbytes;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ciout_put_efile:
2898c2ecf20Sopenharmony_ci	fdput(efile);
2908c2ecf20Sopenharmony_ciout:
2918c2ecf20Sopenharmony_ci	mutex_unlock(&pressure_event_lock);
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	return ret;
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_civoid zswapd_pressure_report(enum zswapd_pressure_level level)
2978c2ecf20Sopenharmony_ci{
2988c2ecf20Sopenharmony_ci	int ret;
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	if (zswapd_press_efd[level] == NULL)
3018c2ecf20Sopenharmony_ci		return;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	ret = eventfd_signal(zswapd_press_efd[level], 1);
3048c2ecf20Sopenharmony_ci	if (ret < 0)
3058c2ecf20Sopenharmony_ci		pr_err("SWAP-MM: %s : level:%u, ret:%d ", __func__, level, ret);
3068c2ecf20Sopenharmony_ci}
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_cistatic u64 zswapd_pid_read(struct cgroup_subsys_state *css, struct cftype *cft)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	return get_zswapd_pid();
3118c2ecf20Sopenharmony_ci}
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_cistatic void zswapd_memcgs_param_parse(int level_num)
3148c2ecf20Sopenharmony_ci{
3158c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = NULL;
3168c2ecf20Sopenharmony_ci	u64 score;
3178c2ecf20Sopenharmony_ci	int i;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	while ((memcg = get_next_memcg(memcg))) {
3208c2ecf20Sopenharmony_ci		score = atomic64_read(&memcg->memcg_reclaimed.app_score);
3218c2ecf20Sopenharmony_ci		for (i = 0; i < level_num; ++i)
3228c2ecf20Sopenharmony_ci			if (score >= zswap_param[i].min_score &&
3238c2ecf20Sopenharmony_ci			    score <= zswap_param[i].max_score)
3248c2ecf20Sopenharmony_ci				break;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci		atomic_set(&memcg->memcg_reclaimed.ub_mem2zram_ratio,
3278c2ecf20Sopenharmony_ci			zswap_param[i].ub_mem2zram_ratio);
3288c2ecf20Sopenharmony_ci		atomic_set(&memcg->memcg_reclaimed.ub_zram2ufs_ratio,
3298c2ecf20Sopenharmony_ci			zswap_param[i].ub_zram2ufs_ratio);
3308c2ecf20Sopenharmony_ci		atomic_set(&memcg->memcg_reclaimed.refault_threshold,
3318c2ecf20Sopenharmony_ci			zswap_param[i].refault_threshold);
3328c2ecf20Sopenharmony_ci	}
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic ssize_t zswapd_memcgs_param_write(struct kernfs_open_file *of, char *buf,
3368c2ecf20Sopenharmony_ci				size_t nbytes, loff_t off)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	char *token = NULL;
3398c2ecf20Sopenharmony_ci	int level_num;
3408c2ecf20Sopenharmony_ci	int i;
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	buf = strstrip(buf);
3438c2ecf20Sopenharmony_ci	token = strsep(&buf, " ");
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	if (!token)
3468c2ecf20Sopenharmony_ci		return -EINVAL;
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci	if (kstrtoint(token, 0, &level_num))
3498c2ecf20Sopenharmony_ci		return -EINVAL;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	if (level_num > ZSWAPD_MAX_LEVEL_NUM)
3528c2ecf20Sopenharmony_ci		return -EINVAL;
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci	mutex_lock(&reclaim_para_lock);
3558c2ecf20Sopenharmony_ci	for (i = 0; i < level_num; ++i) {
3568c2ecf20Sopenharmony_ci		token = strsep(&buf, " ");
3578c2ecf20Sopenharmony_ci		if (!token)
3588c2ecf20Sopenharmony_ci			goto out;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci		if (kstrtoint(token, 0, &zswap_param[i].min_score) ||
3618c2ecf20Sopenharmony_ci			zswap_param[i].min_score > MAX_APP_SCORE)
3628c2ecf20Sopenharmony_ci			goto out;
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci		token = strsep(&buf, " ");
3658c2ecf20Sopenharmony_ci		if (!token)
3668c2ecf20Sopenharmony_ci			goto out;
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci		if (kstrtoint(token, 0, &zswap_param[i].max_score) ||
3698c2ecf20Sopenharmony_ci			zswap_param[i].max_score > MAX_APP_SCORE)
3708c2ecf20Sopenharmony_ci			goto out;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci		token = strsep(&buf, " ");
3738c2ecf20Sopenharmony_ci		if (!token)
3748c2ecf20Sopenharmony_ci			goto out;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci		if (kstrtoint(token, 0, &zswap_param[i].ub_mem2zram_ratio) ||
3778c2ecf20Sopenharmony_ci			zswap_param[i].ub_mem2zram_ratio > MAX_RATIO)
3788c2ecf20Sopenharmony_ci			goto out;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci		token = strsep(&buf, " ");
3818c2ecf20Sopenharmony_ci		if (!token)
3828c2ecf20Sopenharmony_ci			goto out;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci		if (kstrtoint(token, 0, &zswap_param[i].ub_zram2ufs_ratio) ||
3858c2ecf20Sopenharmony_ci			zswap_param[i].ub_zram2ufs_ratio > MAX_RATIO)
3868c2ecf20Sopenharmony_ci			goto out;
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci		token = strsep(&buf, " ");
3898c2ecf20Sopenharmony_ci		if (!token)
3908c2ecf20Sopenharmony_ci			goto out;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci		if (kstrtoint(token, 0, &zswap_param[i].refault_threshold))
3938c2ecf20Sopenharmony_ci			goto out;
3948c2ecf20Sopenharmony_ci	}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	zswapd_memcgs_param_parse(level_num);
3978c2ecf20Sopenharmony_ci	mutex_unlock(&reclaim_para_lock);
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	return nbytes;
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ciout:
4028c2ecf20Sopenharmony_ci	mutex_unlock(&reclaim_para_lock);
4038c2ecf20Sopenharmony_ci	return -EINVAL;
4048c2ecf20Sopenharmony_ci}
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_cistatic ssize_t zswapd_single_memcg_param_write(struct kernfs_open_file *of,
4078c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
4088c2ecf20Sopenharmony_ci{
4098c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
4108c2ecf20Sopenharmony_ci	unsigned int ub_mem2zram_ratio;
4118c2ecf20Sopenharmony_ci	unsigned int ub_zram2ufs_ratio;
4128c2ecf20Sopenharmony_ci	unsigned int refault_threshold;
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	buf = strstrip(buf);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	if (sscanf(buf, "%u %u %u", &ub_mem2zram_ratio, &ub_zram2ufs_ratio,
4178c2ecf20Sopenharmony_ci			&refault_threshold) != 3)
4188c2ecf20Sopenharmony_ci		return -EINVAL;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	if (ub_mem2zram_ratio > MAX_RATIO || ub_zram2ufs_ratio > MAX_RATIO ||
4218c2ecf20Sopenharmony_ci	    refault_threshold > MAX_RATIO)
4228c2ecf20Sopenharmony_ci		return -EINVAL;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	atomic_set(&memcg->memcg_reclaimed.ub_mem2zram_ratio,
4258c2ecf20Sopenharmony_ci		ub_mem2zram_ratio);
4268c2ecf20Sopenharmony_ci	atomic_set(&memcg->memcg_reclaimed.ub_zram2ufs_ratio,
4278c2ecf20Sopenharmony_ci		ub_zram2ufs_ratio);
4288c2ecf20Sopenharmony_ci	atomic_set(&memcg->memcg_reclaimed.refault_threshold,
4298c2ecf20Sopenharmony_ci		refault_threshold);
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	return nbytes;
4328c2ecf20Sopenharmony_ci}
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_cistatic ssize_t mem_cgroup_zram_wm_ratio_write(struct kernfs_open_file *of,
4358c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
4368c2ecf20Sopenharmony_ci{
4378c2ecf20Sopenharmony_ci	unsigned int ratio;
4388c2ecf20Sopenharmony_ci	int ret;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	buf = strstrip(buf);
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	ret = kstrtouint(buf, 10, &ratio);
4438c2ecf20Sopenharmony_ci	if (ret)
4448c2ecf20Sopenharmony_ci		return -EINVAL;
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	if (ratio > MAX_RATIO)
4478c2ecf20Sopenharmony_ci		return -EINVAL;
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	atomic_set(&zram_wm_ratio, ratio);
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	return nbytes;
4528c2ecf20Sopenharmony_ci}
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_cistatic ssize_t mem_cgroup_compress_ratio_write(struct kernfs_open_file *of,
4558c2ecf20Sopenharmony_ci				char *buf, size_t nbytes, loff_t off)
4568c2ecf20Sopenharmony_ci{
4578c2ecf20Sopenharmony_ci	unsigned int ratio;
4588c2ecf20Sopenharmony_ci	int ret;
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci	buf = strstrip(buf);
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	ret = kstrtouint(buf, 10, &ratio);
4638c2ecf20Sopenharmony_ci	if (ret)
4648c2ecf20Sopenharmony_ci		return -EINVAL;
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	if (ratio > MAX_RATIO)
4678c2ecf20Sopenharmony_ci		return -EINVAL;
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	atomic_set(&compress_ratio, ratio);
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	return nbytes;
4728c2ecf20Sopenharmony_ci}
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_cistatic int zswapd_pressure_show(struct seq_file *m, void *v)
4758c2ecf20Sopenharmony_ci{
4768c2ecf20Sopenharmony_ci	zswapd_status_show(m);
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	return 0;
4798c2ecf20Sopenharmony_ci}
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_cistatic int memcg_active_app_info_list_show(struct seq_file *m, void *v)
4828c2ecf20Sopenharmony_ci{
4838c2ecf20Sopenharmony_ci	struct mem_cgroup_per_node *mz = NULL;
4848c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = NULL;
4858c2ecf20Sopenharmony_ci	struct lruvec *lruvec = NULL;
4868c2ecf20Sopenharmony_ci	unsigned long eswap_size;
4878c2ecf20Sopenharmony_ci	unsigned long anon_size;
4888c2ecf20Sopenharmony_ci	unsigned long zram_size;
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci	while ((memcg = get_next_memcg(memcg))) {
4918c2ecf20Sopenharmony_ci		u64 score = atomic64_read(&memcg->memcg_reclaimed.app_score);
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci		mz = mem_cgroup_nodeinfo(memcg, 0);
4948c2ecf20Sopenharmony_ci		if (!mz) {
4958c2ecf20Sopenharmony_ci			get_next_memcg_break(memcg);
4968c2ecf20Sopenharmony_ci			return 0;
4978c2ecf20Sopenharmony_ci		}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci		lruvec = &mz->lruvec;
5008c2ecf20Sopenharmony_ci		if (!lruvec) {
5018c2ecf20Sopenharmony_ci			get_next_memcg_break(memcg);
5028c2ecf20Sopenharmony_ci			return 0;
5038c2ecf20Sopenharmony_ci		}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci		anon_size = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON,
5068c2ecf20Sopenharmony_ci			MAX_NR_ZONES) +	lruvec_lru_size(lruvec,
5078c2ecf20Sopenharmony_ci			LRU_INACTIVE_ANON, MAX_NR_ZONES);
5088c2ecf20Sopenharmony_ci		eswap_size = memcg_data_size(memcg, SWAP_SIZE);
5098c2ecf20Sopenharmony_ci		zram_size = memcg_data_size(memcg, CACHE_SIZE);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci		if (anon_size + zram_size + eswap_size == 0)
5128c2ecf20Sopenharmony_ci			continue;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci		if (!strlen(memcg->name))
5158c2ecf20Sopenharmony_ci			continue;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci		anon_size *= PAGE_SIZE / SZ_1K;
5188c2ecf20Sopenharmony_ci		zram_size *= PAGE_SIZE / SZ_1K;
5198c2ecf20Sopenharmony_ci		eswap_size *= PAGE_SIZE / SZ_1K;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci		seq_printf(m, "%s %llu %lu %lu %lu %llu\n", memcg->name, score,
5228c2ecf20Sopenharmony_ci			anon_size, zram_size, eswap_size,
5238c2ecf20Sopenharmony_ci			memcg->memcg_reclaimed.reclaimed_pagefault);
5248c2ecf20Sopenharmony_ci	}
5258c2ecf20Sopenharmony_ci	return 0;
5268c2ecf20Sopenharmony_ci}
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
5298c2ecf20Sopenharmony_cistatic int avail_buffers_params_show(struct seq_file *m, void *v)
5308c2ecf20Sopenharmony_ci{
5318c2ecf20Sopenharmony_ci	seq_printf(m, "avail_buffers: %u\n", atomic_read(&avail_buffers));
5328c2ecf20Sopenharmony_ci	seq_printf(m, "min_avail_buffers: %u\n", atomic_read(&min_avail_buffers));
5338c2ecf20Sopenharmony_ci	seq_printf(m, "high_avail_buffers: %u\n", atomic_read(&high_avail_buffers));
5348c2ecf20Sopenharmony_ci	seq_printf(m, "free_swap_threshold: %llu\n",
5358c2ecf20Sopenharmony_ci		atomic64_read(&free_swap_threshold) * PAGE_SIZE / SZ_1M);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	return 0;
5388c2ecf20Sopenharmony_ci}
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_cistatic int zswapd_max_reclaim_size_show(struct seq_file *m, void *v)
5418c2ecf20Sopenharmony_ci{
5428c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_max_reclaim_size: %u\n",
5438c2ecf20Sopenharmony_ci		atomic_read(&max_reclaim_size));
5448c2ecf20Sopenharmony_ci
5458c2ecf20Sopenharmony_ci	return 0;
5468c2ecf20Sopenharmony_ci}
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_cistatic int buffers_ratio_params_show(struct seq_file *m, void *v)
5498c2ecf20Sopenharmony_ci{
5508c2ecf20Sopenharmony_ci	seq_printf(m, "inactive_file_ratio: %u\n", atomic_read(&inactive_file_ratio));
5518c2ecf20Sopenharmony_ci	seq_printf(m, "active_file_ratio: %u\n", atomic_read(&active_file_ratio));
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci	return 0;
5548c2ecf20Sopenharmony_ci}
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistatic u64 area_anon_refault_threshold_read(struct cgroup_subsys_state *css,
5578c2ecf20Sopenharmony_ci					struct cftype *cft)
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	return atomic64_read(&area_anon_refault_threshold);
5608c2ecf20Sopenharmony_ci}
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_cistatic u64 empty_round_skip_interval_read(struct cgroup_subsys_state *css,
5638c2ecf20Sopenharmony_ci					struct cftype *cft)
5648c2ecf20Sopenharmony_ci{
5658c2ecf20Sopenharmony_ci	return atomic64_read(&empty_round_skip_interval);
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_cistatic u64 max_skip_interval_read(struct cgroup_subsys_state *css,
5698c2ecf20Sopenharmony_ci					struct cftype *cft)
5708c2ecf20Sopenharmony_ci{
5718c2ecf20Sopenharmony_ci	return atomic64_read(&max_skip_interval);
5728c2ecf20Sopenharmony_ci}
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_cistatic u64 empty_round_check_threshold_read(struct cgroup_subsys_state *css,
5758c2ecf20Sopenharmony_ci					struct cftype *cft)
5768c2ecf20Sopenharmony_ci{
5778c2ecf20Sopenharmony_ci	return atomic64_read(&empty_round_check_threshold);
5788c2ecf20Sopenharmony_ci}
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_cistatic u64 anon_refault_snapshot_min_interval_read(
5818c2ecf20Sopenharmony_ci		struct cgroup_subsys_state *css, struct cftype *cft)
5828c2ecf20Sopenharmony_ci{
5838c2ecf20Sopenharmony_ci	return atomic64_read(&anon_refault_snapshot_min_interval);
5848c2ecf20Sopenharmony_ci}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_cistatic u64 zram_critical_threshold_read(struct cgroup_subsys_state *css,
5878c2ecf20Sopenharmony_ci					struct cftype *cft)
5888c2ecf20Sopenharmony_ci{
5898c2ecf20Sopenharmony_ci	return atomic64_read(&zram_critical_threshold);
5908c2ecf20Sopenharmony_ci}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_cistatic int zswapd_memcgs_param_show(struct seq_file *m, void *v)
5938c2ecf20Sopenharmony_ci{
5948c2ecf20Sopenharmony_ci	int i;
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci	for (i = 0; i < ZSWAPD_MAX_LEVEL_NUM; ++i) {
5978c2ecf20Sopenharmony_ci		seq_printf(m, "level %d min score: %u\n", i,
5988c2ecf20Sopenharmony_ci			zswap_param[i].min_score);
5998c2ecf20Sopenharmony_ci		seq_printf(m, "level %d max score: %u\n", i,
6008c2ecf20Sopenharmony_ci			zswap_param[i].max_score);
6018c2ecf20Sopenharmony_ci		seq_printf(m, "level %d ub_mem2zram_ratio: %u\n", i,
6028c2ecf20Sopenharmony_ci			zswap_param[i].ub_mem2zram_ratio);
6038c2ecf20Sopenharmony_ci		seq_printf(m, "level %d ub_zram2ufs_ratio: %u\n", i,
6048c2ecf20Sopenharmony_ci			zswap_param[i].ub_zram2ufs_ratio);
6058c2ecf20Sopenharmony_ci		seq_printf(m, "level %d refault_threshold: %u\n", i,
6068c2ecf20Sopenharmony_ci			zswap_param[i].refault_threshold);
6078c2ecf20Sopenharmony_ci	}
6088c2ecf20Sopenharmony_ci
6098c2ecf20Sopenharmony_ci	return 0;
6108c2ecf20Sopenharmony_ci}
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_cistatic int zswapd_single_memcg_param_show(struct seq_file *m, void *v)
6138c2ecf20Sopenharmony_ci{
6148c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci	seq_printf(m, "memcg score: %llu\n",
6178c2ecf20Sopenharmony_ci		atomic64_read(&memcg->memcg_reclaimed.app_score));
6188c2ecf20Sopenharmony_ci	seq_printf(m, "memcg ub_mem2zram_ratio: %u\n",
6198c2ecf20Sopenharmony_ci		atomic_read(&memcg->memcg_reclaimed.ub_mem2zram_ratio));
6208c2ecf20Sopenharmony_ci	seq_printf(m, "memcg ub_zram2ufs_ratio: %u\n",
6218c2ecf20Sopenharmony_ci		atomic_read(&memcg->memcg_reclaimed.ub_zram2ufs_ratio));
6228c2ecf20Sopenharmony_ci	seq_printf(m, "memcg refault_threshold: %u\n",
6238c2ecf20Sopenharmony_ci		atomic_read(&memcg->memcg_reclaimed.refault_threshold));
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_ci	return 0;
6268c2ecf20Sopenharmony_ci}
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_cistatic int zram_wm_ratio_show(struct seq_file *m, void *v)
6298c2ecf20Sopenharmony_ci{
6308c2ecf20Sopenharmony_ci	seq_printf(m, "zram_wm_ratio: %u\n", atomic_read(&zram_wm_ratio));
6318c2ecf20Sopenharmony_ci
6328c2ecf20Sopenharmony_ci	return 0;
6338c2ecf20Sopenharmony_ci}
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_cistatic int compress_ratio_show(struct seq_file *m, void *v)
6368c2ecf20Sopenharmony_ci{
6378c2ecf20Sopenharmony_ci	seq_printf(m, "compress_ratio: %u\n", atomic_read(&compress_ratio));
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	return 0;
6408c2ecf20Sopenharmony_ci}
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_cistatic int zswapd_vmstat_show(struct seq_file *m, void *v)
6438c2ecf20Sopenharmony_ci{
6448c2ecf20Sopenharmony_ci#ifdef CONFIG_VM_EVENT_COUNTERS
6458c2ecf20Sopenharmony_ci	unsigned long *vm_buf = NULL;
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	vm_buf = kzalloc(sizeof(struct vm_event_state), GFP_KERNEL);
6488c2ecf20Sopenharmony_ci	if (!vm_buf)
6498c2ecf20Sopenharmony_ci		return -ENOMEM;
6508c2ecf20Sopenharmony_ci	all_vm_events(vm_buf);
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_wake_up:%lu\n", vm_buf[ZSWAPD_WAKEUP]);
6538c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_area_refault:%lu\n", vm_buf[ZSWAPD_REFAULT]);
6548c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_medium_press:%lu\n", vm_buf[ZSWAPD_MEDIUM_PRESS]);
6558c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_critical_press:%lu\n", vm_buf[ZSWAPD_CRITICAL_PRESS]);
6568c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_memcg_ratio_skip:%lu\n", vm_buf[ZSWAPD_MEMCG_RATIO_SKIP]);
6578c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_memcg_refault_skip:%lu\n", vm_buf[ZSWAPD_MEMCG_REFAULT_SKIP]);
6588c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_swapout:%lu\n", vm_buf[ZSWAPD_SWAPOUT]);
6598c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_snapshot_times:%lu\n", vm_buf[ZSWAPD_SNAPSHOT_TIMES]);
6608c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_reclaimed:%lu\n", vm_buf[ZSWAPD_RECLAIMED]);
6618c2ecf20Sopenharmony_ci	seq_printf(m, "zswapd_scanned:%lu\n", vm_buf[ZSWAPD_SCANNED]);
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci	kfree(vm_buf);
6648c2ecf20Sopenharmony_ci#endif
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	return 0;
6678c2ecf20Sopenharmony_ci}
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_cistatic int eswap_info_show(struct seq_file *m, void *v)
6708c2ecf20Sopenharmony_ci{
6718c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
6728c2ecf20Sopenharmony_ci	unsigned long long eswap_size;
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci	eswap_size = memcg_data_size(memcg, WRITE_SIZE) / SZ_1K;
6758c2ecf20Sopenharmony_ci	seq_printf(m, "Total Swapout Size: %llu kB\n", eswap_size);
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci	return 0;
6788c2ecf20Sopenharmony_ci}
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_civoid memcg_eswap_info_show(struct seq_file *m)
6818c2ecf20Sopenharmony_ci{
6828c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
6838c2ecf20Sopenharmony_ci	struct mem_cgroup_per_node *mz = NULL;
6848c2ecf20Sopenharmony_ci	struct lruvec *lruvec = NULL;
6858c2ecf20Sopenharmony_ci	unsigned long anon;
6868c2ecf20Sopenharmony_ci	unsigned long file;
6878c2ecf20Sopenharmony_ci	unsigned long zram;
6888c2ecf20Sopenharmony_ci	unsigned long eswap;
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci	mz = mem_cgroup_nodeinfo(memcg, 0);
6918c2ecf20Sopenharmony_ci	if (!mz)
6928c2ecf20Sopenharmony_ci		return;
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	lruvec = &mz->lruvec;
6958c2ecf20Sopenharmony_ci	if (!lruvec)
6968c2ecf20Sopenharmony_ci		return;
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) +
6998c2ecf20Sopenharmony_ci		lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES);
7008c2ecf20Sopenharmony_ci	file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
7018c2ecf20Sopenharmony_ci		lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES);
7028c2ecf20Sopenharmony_ci	zram = memcg_data_size(memcg, CACHE_SIZE) / SZ_1K;
7038c2ecf20Sopenharmony_ci	eswap = memcg_data_size(memcg, SWAP_SIZE) / SZ_1K;
7048c2ecf20Sopenharmony_ci	anon *= PAGE_SIZE / SZ_1K;
7058c2ecf20Sopenharmony_ci	file *= PAGE_SIZE / SZ_1K;
7068c2ecf20Sopenharmony_ci	seq_printf(m, "Anon:\t%12lu kB\nFile:\t%12lu kB\nzram:\t%12lu kB\nEswap:\t%12lu kB\n",
7078c2ecf20Sopenharmony_ci		anon, file, zram, eswap);
7088c2ecf20Sopenharmony_ci}
7098c2ecf20Sopenharmony_ci#endif
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_cistatic struct cftype zswapd_policy_files[] = {
7128c2ecf20Sopenharmony_ci	{
7138c2ecf20Sopenharmony_ci		.name = "active_app_info_list",
7148c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7158c2ecf20Sopenharmony_ci		.seq_show = memcg_active_app_info_list_show,
7168c2ecf20Sopenharmony_ci	},
7178c2ecf20Sopenharmony_ci	{
7188c2ecf20Sopenharmony_ci		.name = "zram_wm_ratio",
7198c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7208c2ecf20Sopenharmony_ci		.write = mem_cgroup_zram_wm_ratio_write,
7218c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7228c2ecf20Sopenharmony_ci		.seq_show = zram_wm_ratio_show,
7238c2ecf20Sopenharmony_ci#endif
7248c2ecf20Sopenharmony_ci	},
7258c2ecf20Sopenharmony_ci	{
7268c2ecf20Sopenharmony_ci		.name = "compress_ratio",
7278c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7288c2ecf20Sopenharmony_ci		.write = mem_cgroup_compress_ratio_write,
7298c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7308c2ecf20Sopenharmony_ci		.seq_show = compress_ratio_show,
7318c2ecf20Sopenharmony_ci#endif
7328c2ecf20Sopenharmony_ci	},
7338c2ecf20Sopenharmony_ci	{
7348c2ecf20Sopenharmony_ci		.name = "zswapd_pressure",
7358c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7368c2ecf20Sopenharmony_ci		.write = zswapd_pressure_event_control,
7378c2ecf20Sopenharmony_ci	},
7388c2ecf20Sopenharmony_ci	{
7398c2ecf20Sopenharmony_ci		.name = "zswapd_pid",
7408c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7418c2ecf20Sopenharmony_ci		.read_u64 = zswapd_pid_read,
7428c2ecf20Sopenharmony_ci	},
7438c2ecf20Sopenharmony_ci	{
7448c2ecf20Sopenharmony_ci		.name = "avail_buffers",
7458c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7468c2ecf20Sopenharmony_ci		.write = avail_buffers_params_write,
7478c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7488c2ecf20Sopenharmony_ci		.seq_show = avail_buffers_params_show,
7498c2ecf20Sopenharmony_ci#endif
7508c2ecf20Sopenharmony_ci	},
7518c2ecf20Sopenharmony_ci	{
7528c2ecf20Sopenharmony_ci		.name = "zswapd_max_reclaim_size",
7538c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7548c2ecf20Sopenharmony_ci		.write = zswapd_max_reclaim_size_write,
7558c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7568c2ecf20Sopenharmony_ci		.seq_show = zswapd_max_reclaim_size_show,
7578c2ecf20Sopenharmony_ci#endif
7588c2ecf20Sopenharmony_ci	},
7598c2ecf20Sopenharmony_ci	{
7608c2ecf20Sopenharmony_ci		.name = "area_anon_refault_threshold",
7618c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7628c2ecf20Sopenharmony_ci		.write_u64 = area_anon_refault_threshold_write,
7638c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7648c2ecf20Sopenharmony_ci		.read_u64 = area_anon_refault_threshold_read,
7658c2ecf20Sopenharmony_ci#endif
7668c2ecf20Sopenharmony_ci	},
7678c2ecf20Sopenharmony_ci	{
7688c2ecf20Sopenharmony_ci		.name = "empty_round_skip_interval",
7698c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7708c2ecf20Sopenharmony_ci		.write_u64 = empty_round_skip_interval_write,
7718c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7728c2ecf20Sopenharmony_ci		.read_u64 = empty_round_skip_interval_read,
7738c2ecf20Sopenharmony_ci#endif
7748c2ecf20Sopenharmony_ci	},
7758c2ecf20Sopenharmony_ci	{
7768c2ecf20Sopenharmony_ci		.name = "max_skip_interval",
7778c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7788c2ecf20Sopenharmony_ci		.write_u64 = max_skip_interval_write,
7798c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7808c2ecf20Sopenharmony_ci		.read_u64 = max_skip_interval_read,
7818c2ecf20Sopenharmony_ci#endif
7828c2ecf20Sopenharmony_ci	},
7838c2ecf20Sopenharmony_ci	{
7848c2ecf20Sopenharmony_ci		.name = "empty_round_check_threshold",
7858c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7868c2ecf20Sopenharmony_ci		.write_u64 = empty_round_check_threshold_write,
7878c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7888c2ecf20Sopenharmony_ci		.read_u64 = empty_round_check_threshold_read,
7898c2ecf20Sopenharmony_ci#endif
7908c2ecf20Sopenharmony_ci	},
7918c2ecf20Sopenharmony_ci	{
7928c2ecf20Sopenharmony_ci		.name = "anon_refault_snapshot_min_interval",
7938c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
7948c2ecf20Sopenharmony_ci		.write_u64 = anon_refault_snapshot_min_interval_write,
7958c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
7968c2ecf20Sopenharmony_ci		.read_u64 = anon_refault_snapshot_min_interval_read,
7978c2ecf20Sopenharmony_ci#endif
7988c2ecf20Sopenharmony_ci	},
7998c2ecf20Sopenharmony_ci	{
8008c2ecf20Sopenharmony_ci		.name = "zswapd_memcgs_param",
8018c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8028c2ecf20Sopenharmony_ci		.write = zswapd_memcgs_param_write,
8038c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
8048c2ecf20Sopenharmony_ci		.seq_show = zswapd_memcgs_param_show,
8058c2ecf20Sopenharmony_ci#endif
8068c2ecf20Sopenharmony_ci	},
8078c2ecf20Sopenharmony_ci	{
8088c2ecf20Sopenharmony_ci		.name = "zswapd_single_memcg_param",
8098c2ecf20Sopenharmony_ci		.write = zswapd_single_memcg_param_write,
8108c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
8118c2ecf20Sopenharmony_ci		.seq_show = zswapd_single_memcg_param_show,
8128c2ecf20Sopenharmony_ci#endif
8138c2ecf20Sopenharmony_ci	},
8148c2ecf20Sopenharmony_ci	{
8158c2ecf20Sopenharmony_ci		.name = "buffer_ratio_params",
8168c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8178c2ecf20Sopenharmony_ci		.write = buffers_ratio_params_write,
8188c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
8198c2ecf20Sopenharmony_ci		.seq_show = buffers_ratio_params_show,
8208c2ecf20Sopenharmony_ci#endif
8218c2ecf20Sopenharmony_ci	},
8228c2ecf20Sopenharmony_ci	{
8238c2ecf20Sopenharmony_ci		.name = "zswapd_pressure_show",
8248c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8258c2ecf20Sopenharmony_ci		.seq_show = zswapd_pressure_show,
8268c2ecf20Sopenharmony_ci	},
8278c2ecf20Sopenharmony_ci	{
8288c2ecf20Sopenharmony_ci		.name = "zram_critical_threshold",
8298c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8308c2ecf20Sopenharmony_ci		.write_u64 = zram_critical_thres_write,
8318c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
8328c2ecf20Sopenharmony_ci		.read_u64 = zram_critical_threshold_read,
8338c2ecf20Sopenharmony_ci#endif
8348c2ecf20Sopenharmony_ci	},
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci#ifdef CONFIG_HYPERHOLD_DEBUG
8378c2ecf20Sopenharmony_ci	{
8388c2ecf20Sopenharmony_ci		.name = "zswapd_vmstat_show",
8398c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8408c2ecf20Sopenharmony_ci		.seq_show = zswapd_vmstat_show,
8418c2ecf20Sopenharmony_ci	},
8428c2ecf20Sopenharmony_ci#endif
8438c2ecf20Sopenharmony_ci	{
8448c2ecf20Sopenharmony_ci		.name = "eswap_info",
8458c2ecf20Sopenharmony_ci		.flags = CFTYPE_ONLY_ON_ROOT,
8468c2ecf20Sopenharmony_ci		.seq_show = eswap_info_show,
8478c2ecf20Sopenharmony_ci	},
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_ci	{ },	/* terminate */
8508c2ecf20Sopenharmony_ci};
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_cistatic int __init zswapd_policy_init(void)
8538c2ecf20Sopenharmony_ci{
8548c2ecf20Sopenharmony_ci	if (!mem_cgroup_disabled())
8558c2ecf20Sopenharmony_ci		WARN_ON(cgroup_add_legacy_cftypes(&memory_cgrp_subsys, zswapd_policy_files));
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	return 0;
8588c2ecf20Sopenharmony_ci}
8598c2ecf20Sopenharmony_cisubsys_initcall(zswapd_policy_init);
860