4 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include "module-data.h"
24 #include "file-helper.h"
26 #include "swap-common.h"
27 #include "memory-cgroup.h"
28 #include "config-parser.h"
29 #include "lowmem-handler.h"
32 #define DEFAULT_ZSWAP_POOL_RATIO (25)
33 #define ZSWAP_FULLNESS_RATIO 0.8
34 #define DEFAULT_ZSWAP_FILE_SIZE MBYTE_TO_BYTE(30)
36 #define ZSWAP_POOL_PERCENT "/sys/module/zswap/parameters/max_pool_percent"
37 #define ZSWAP_POOL_TYPE "/sys/module/zswap/parameters/zpool"
38 #define ZSWAP_WRITTEN_SIZE "/sys/kernel/debug/zswap/written_back_pages"
39 #define ZSWAP_ENABLED "/sys/module/zswap/parameters/enabled"
41 struct swap_zswap_control {
42 char crypt_type[MAX_TYPE_LENGTH];
46 unsigned long zswap_reclaim_bytes;
47 char zpool_type[MAX_TYPE_LENGTH];
50 static struct swap_zswap_control zswap_control = {
52 .swapfile = SWAP_FILE_NAME,
53 .zpool_ratio = DEFAULT_ZSWAP_POOL_RATIO,
54 .zswap_file_size = DEFAULT_ZSWAP_FILE_SIZE,
55 .zswap_reclaim_bytes = 0,
59 static int swap_zswap_activate(void *data)
61 struct swap_module_ops *swap = (struct swap_module_ops *)data;
64 zswap_control.zswap_reclaim_bytes =
65 zswap_control.zswap_file_size * ZSWAP_FULLNESS_RATIO;
67 r = swap_set_file(zswap_control.swapfile, swap, zswap_control.crypt_type);
71 r = fwrite_int(ZSWAP_POOL_PERCENT, zswap_control.zpool_ratio);
73 _E("fail to write max_pool_percent: %.2f", zswap_control.zpool_ratio);
77 r = fwrite_str(ZSWAP_POOL_TYPE, zswap_control.zpool_type);
79 _E("fail to change zpool : %s use default", ZSWAP_POOL_TYPE);
81 r = fwrite_int(ZSWAP_ENABLED, true);
83 _E("fail to enable zswap");
88 static int swap_zswap_reclaim(void *data)
91 unsigned int swap_size;
93 r = fread_uint(ZSWAP_WRITTEN_SIZE, &swap_size);
95 _E("fail to read written swap size");
99 swap_size <<= PAGE_SHIFT;
100 if (swap_size <= zswap_control.zswap_reclaim_bytes)
104 * In this case, swap storage is almost full.
105 * It means that there are many background processes or
106 * some process makes memory leak.
107 * So, it requires to trigger proactive oom killer.
110 lowmem_trigger_swap_reclaim(CGROUP_ROOT, swap_size);
114 static int swap_zswap_init(void *data)
116 struct swap_module_ops *swap = (struct swap_module_ops *)data;
118 if (access(ZSWAP_POOL_PERCENT, R_OK) != 0)
121 swap->k_size = BYTE_TO_KBYTE(zswap_control.zswap_file_size);
125 static int swap_zswap_conf(void *data)
127 struct zswap_conf *zswap_conf = (struct zswap_conf *)data;
129 _E("[DEBUG] Zswap configuration should not be NULL");
130 return RESOURCED_ERROR_FAIL;
133 if (check_valid_compressor(zswap_conf->type) == RESOURCED_ERROR_NONE)
134 strncpy(zswap_control.crypt_type, zswap_conf->type, MAX_TYPE_LENGTH-1);
136 if (zswap_conf->filesize > 0)
137 zswap_control.zswap_file_size = zswap_conf->filesize;
139 if (zswap_conf->pool_ratio > 0.0)
140 zswap_control.zpool_ratio = zswap_conf->pool_ratio;
142 if (!is_empty(zswap_conf->pool_type))
143 strncpy(zswap_control.zpool_type, zswap_conf->pool_type, MAX_TYPE_LENGTH-1);
145 memset(zswap_control.zpool_type, 0, MAX_TYPE_LENGTH);
147 _I("[DEBUG] zswap type = %s", zswap_control.crypt_type);
148 _I("[DEBUG] zswap filesize = %ld", zswap_control.zswap_file_size);
149 _I("[DEBUG] zswap pool ratio = %f", zswap_control.zpool_ratio);
150 _I("[DEBUG] zswap pool type = %s", zswap_control.zpool_type);
152 return RESOURCED_ERROR_NONE;
156 static struct swap_module_ops swap_zswap_ops = {
158 .type = SWAP_TYPE_ZSWAP,
160 .priority = SWAP_PRI_DISABLE,
162 .init = swap_zswap_init,
163 .activate = swap_zswap_activate,
164 .reclaim = swap_zswap_reclaim,
165 .conf = swap_zswap_conf,
167 SWAP_MODULE_REGISTER(&swap_zswap_ops)