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 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)
58 unsigned long long total_bytes;
59 static unsigned long long last_total_bytes;
62 _D("call zram compact");
63 r = fread_ulonglong(SWAP_ZRAM_MEM_USED_TOTAL, &total_bytes);
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_bytes - last_total_bytes) < MBYTE_TO_BYTE(1))
76 last_total_bytes = total_bytes;
77 r = fwrite_int(SWAP_ZRAM_COMPACT, 1);
79 _E("fail to write %s", SWAP_ZRAM_COMPACT);
83 r = fread_ulonglong(SWAP_ZRAM_MEM_USED_TOTAL, &total_bytes);
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 long long 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_ulonglong(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_ulonglong(SWAP_ZRAM_DISK_SIZE, swap_size_bytes);
140 _E("fail to write disk_size");
144 r = fread_ulonglong(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 (%llu) less than expected swap size (%llu)",
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 long long swap_total_bytes = 0;
174 static bool zram_compact;
175 unsigned long long swap_available_bytes;
176 unsigned long long swap_usage_bytes;
177 float swapcg_usage_ratio;
178 unsigned int ram_available;
180 swap_available_bytes = KBYTE_TO_BYTE(proc_get_swap_free());
183 * Most kernel doesn't support migration and compaction of zmalloc.
184 * So, if zmalloc uses much kernel memory,
185 * there is no high order buddy due to memory fragmentation.
186 * It causes system sluggish or lockup problems.
187 * In case of no high order buddy, trigger LMK.
189 if (lowmem_fragmentated()) {
191 lowmem_trigger_swap_reclaim(CGROUP_ROOT, zram_control.zram_reclaim_bytes);
192 zram_compact = false;
200 if (swap_available_bytes >= zram_control.zram_reclaim_bytes)
204 r = swap_zram_compact();
211 ram_available = proc_get_mem_available();
212 if (ram_available > lowmem_get_proactive_thres())
216 * In this case, swap is almost full but can't comapt zram any longer.
217 * It means that there are many background processes or
218 * some process makes memory leak.
219 * So, it requires to trigger proactive oom killer.
220 * At first, check usage of swap cgroup.
221 * If swap usage of this cgroup is higher, run LMK about background applications.
222 * Otherwise, need to check all processes in order to find mallicious process.
224 if (!swap_total_bytes)
225 swap_total_bytes = KBYTE_TO_BYTE(proc_get_swap_total());
227 r = memcg_get_swap_usage(MEMCG_LOW_GROUP_PATH, &swap_usage_bytes);
230 swapcg_usage_ratio = (float)(swap_usage_bytes / (swap_total_bytes - swap_available_bytes) *100);
231 if (swapcg_usage_ratio > SWAPCG_CHECK_RATIO)
236 lowmem_trigger_swap_reclaim(type, zram_control.zram_reclaim_bytes);
237 zram_compact = false;
241 static int swap_zram_init(void *data)
243 struct swap_module_ops *swap = (struct swap_module_ops *)data;
245 if (access(swap->path, R_OK) != 0)
248 swap->k_size = lowmem_get_ktotalram() * zram_control.ratio;
250 if (zram_control.max_comp_streams < 0) {
251 int cpu = proc_get_cpu_number();
253 zram_control.max_comp_streams =
255 * On big.LITTLE we can have 8 cores visible
256 * but there can be used 4. Let's limit it to
257 * 4 if there is no specified value in .conf
267 static int swap_zram_conf(void *data)
269 struct zram_conf *zram_conf = (struct zram_conf *)data;
271 _E("Zram configuration should not be NULL");
272 return RESOURCED_ERROR_FAIL;
275 if (!is_empty(zram_conf->algorithm))
276 strncpy(zram_control.comp_algorithm, zram_conf->algorithm, MAX_TYPE_LENGTH - 1);
278 if (zram_conf->ratio > 0.0)
279 zram_control.ratio = zram_conf->ratio;
281 _I("[SWAP] zram algorithm = %s", zram_control.comp_algorithm);
282 _I("[SWAP] zram ratio = %f", zram_control.ratio);
284 return RESOURCED_ERROR_NONE;
287 static struct swap_module_ops swap_zram_ops = {
289 .type = SWAP_TYPE_ZRAM,
290 .path = "/dev/zram0",
291 .priority = SWAP_PRI_DEFAULT,
293 .init = swap_zram_init,
294 .activate = swap_zram_activate,
295 .reclaim = swap_zram_reclaim,
296 .conf = swap_zram_conf,
298 SWAP_MODULE_REGISTER(&swap_zram_ops)