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"
31 #define SWAP_ZRAM_DISK_SIZE SWAP_ZRAM_SYSFILE"disksize"
32 #define SWAP_ZRAM_MAX_COMP_STREAMS SWAP_ZRAM_SYSFILE"max_comp_streams"
33 #define SWAP_ZRAM_COMP_ALGORITHM SWAP_ZRAM_SYSFILE"comp_algorithm"
34 #define SWAP_ZRAM_COMPACT SWAP_ZRAM_SYSFILE"compact"
35 #define SWAP_ZRAM_MEM_USED_TOTAL SWAP_ZRAM_SYSFILE"mem_used_total"
37 #define DEFAULT_ZRAM_COMPRESSOR "lz4"
38 #define DEFAULT_ZRAM_RATIO ((double) 0.25)
39 #define ZRAM_FULLNESS_RATIO 0.8
40 #define SWAPCG_CHECK_RATIO 5 /* 5 % of total swap */
42 struct swap_zram_control {
44 char comp_algorithm[MAX_TYPE_LENGTH];
46 unsigned long zram_reclaim_bytes;
49 static struct swap_zram_control zram_control = {
50 .max_comp_streams = -1,
51 .comp_algorithm = DEFAULT_ZRAM_COMPRESSOR,
52 .ratio = DEFAULT_ZRAM_RATIO,
53 .zram_reclaim_bytes = 0,
56 static int swap_zram_compact(void)
59 static unsigned int last_total;
62 _D("call zram compact");
63 r = fread_uint(SWAP_ZRAM_MEM_USED_TOTAL, &total);
65 _E("fail to read %s", SWAP_ZRAM_MEM_USED_TOTAL);
70 * Until zram size not increased of at least 1 MB from last compaction
71 * then it not makes any sense to compact it again.
73 if ((total - last_total) < MBYTE_TO_BYTE(1))
77 r = fwrite_int(SWAP_ZRAM_COMPACT, 1);
79 _E("fail to write %s", SWAP_ZRAM_COMPACT);
83 r = fread_uint(SWAP_ZRAM_MEM_USED_TOTAL, &total);
85 _E("fail to read %s", SWAP_ZRAM_MEM_USED_TOTAL);
92 static int swap_zram_activate(void *data)
94 struct swap_module_ops *swap = (struct swap_module_ops *)data;
95 unsigned int swap_size_bytes, read_size_bytes;
98 swap_size_bytes = KBYTE_TO_BYTE(swap->k_size);
99 zram_control.zram_reclaim_bytes =
100 swap_size_bytes - (swap_size_bytes * ZRAM_FULLNESS_RATIO);
102 if (swap_is_on(swap->path))
105 r = fwrite_int(SWAP_ZRAM_MAX_COMP_STREAMS,
106 zram_control.max_comp_streams);
108 _E("fail to write max_comp_streams");
112 r = fwrite_str(SWAP_ZRAM_COMP_ALGORITHM,
113 zram_control.comp_algorithm);
116 * if it fails to set compressor described in .conf file,
117 * then try again with default compressor.
119 _I("failed to write comp_algorithm: %s, try default: %s",
120 zram_control.comp_algorithm,
121 DEFAULT_ZRAM_COMPRESSOR);
122 r = fwrite_str(SWAP_ZRAM_COMP_ALGORITHM,
123 DEFAULT_ZRAM_COMPRESSOR);
125 _E("fail to write comp_algrithm");
130 r = fread_uint(SWAP_ZRAM_DISK_SIZE, &read_size_bytes);
132 _E("fail to read zram disk_size");
136 /* disksize can be pre-fixed by other means, do not set size in that case */
137 if (read_size_bytes == 0) {
138 r = fwrite_uint(SWAP_ZRAM_DISK_SIZE, swap_size_bytes);
140 _E("fail to write disk_size");
144 r = fread_uint(SWAP_ZRAM_DISK_SIZE, &read_size_bytes);
146 _E("fail to read zram disk_size");
150 /* Check if zram was sucessfully initialized (zcomp rollback case) */
151 if (read_size_bytes < swap_size_bytes) {
152 _E("swap size (%d) less than expected swap size (%d)",
153 read_size_bytes, swap_size_bytes);
154 return RESOURCED_ERROR_OUT_OF_MEMORY;
158 r = do_mkswap(swap->path);
160 _E("Failed to make swap device(%s), exit code: %d", swap->path, r);
163 _E("Failed to make swap device(%s): %m", swap->path);
170 static int swap_zram_reclaim(void *data)
173 static unsigned int swap_total = 0;
174 static bool zram_compact;
175 unsigned long swap_available;
176 unsigned int swap_usage;
177 float swapcg_usage_ratio;
178 unsigned int ram_available;
180 swap_available = KBYTE_TO_BYTE(proc_get_swap_free());
182 _D("swap available %lu, reclaimg byte %lu", swap_available, zram_control.zram_reclaim_bytes);
185 * Most kernel doesn't support migration and compaction of zmalloc.
186 * So, if zmalloc uses much kernel memory,
187 * there is no high order buddy due to memory fragmentation.
188 * It causes system sluggish or lockup problems.
189 * In case of no high order buddy, trigger LMK.
191 if (lowmem_fragmentated()) {
193 lowmem_trigger_swap_reclaim(CGROUP_ROOT, zram_control.zram_reclaim_bytes);
194 zram_compact = false;
202 if (swap_available >= zram_control.zram_reclaim_bytes)
206 r = swap_zram_compact();
213 ram_available = proc_get_mem_available();
214 if (ram_available > lowmem_get_proactive_thres())
218 * In this case, swap is almost full but can't comapt zram any longer.
219 * It means that there are many background processes or
220 * some process makes memory leak.
221 * So, it requires to trigger proactive oom killer.
222 * At first, check usage of swap cgroup.
223 * If swap usage of this cgroup is higher, run LMK about background applications.
224 * Otherwise, need to check all processes in order to find mallicious process.
227 swap_total = proc_get_swap_total();
229 r = memcg_get_swap_usage(MEMCG_LOW_GROUP_PATH, &swap_usage);
232 swapcg_usage_ratio = (float)(swap_usage / (swap_total - swap_available) *100);
233 if (swapcg_usage_ratio > SWAPCG_CHECK_RATIO)
238 lowmem_trigger_swap_reclaim(type, zram_control.zram_reclaim_bytes);
239 zram_compact = false;
243 static int swap_zram_init(void *data)
245 struct swap_module_ops *swap = (struct swap_module_ops *)data;
247 if (access(swap->path, R_OK) != 0)
250 swap->k_size = lowmem_get_ktotalram() * zram_control.ratio;
252 if (zram_control.max_comp_streams < 0) {
253 int cpu = proc_get_cpu_number();
255 zram_control.max_comp_streams =
257 * On big.LITTLE we can have 8 cores visible
258 * but there can be used 4. Let's limit it to
259 * 4 if there is no specified value in .conf
269 static int swap_zram_conf(void *data)
271 struct zram_conf *zram_conf = (struct zram_conf *)data;
273 _E("Zram configuration should not be NULL");
274 return RESOURCED_ERROR_FAIL;
277 if (!is_empty(zram_conf->algorithm))
278 strncpy(zram_control.comp_algorithm, zram_conf->algorithm, MAX_TYPE_LENGTH - 1);
280 if (zram_conf->ratio > 0.0)
281 zram_control.ratio = zram_conf->ratio;
283 _I("[DEBUG] zram algorithm = %s", zram_control.comp_algorithm);
284 _I("[DEBUG] zram ratio = %f", zram_control.ratio);
286 return RESOURCED_ERROR_NONE;
289 static struct swap_module_ops swap_zram_ops = {
291 .type = SWAP_TYPE_ZRAM,
292 .path = "/dev/zram0",
293 .priority = SWAP_PRI_DEFAULT,
295 .init = swap_zram_init,
296 .activate = swap_zram_activate,
297 .reclaim = swap_zram_reclaim,
298 .conf = swap_zram_conf,
300 SWAP_MODULE_REGISTER(&swap_zram_ops)