Remove useless source code
[platform/core/system/resourced.git] / src / resource-optimizer / memory / swap / zswap.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #include "macro.h"
20 #include "module.h"
21 #include "module-data.h"
22 #include "trace.h"
23 #include "util.h"
24 #include "file-helper.h"
25 #include "procfs.h"
26 #include "swap-common.h"
27 #include "memory-cgroup.h"
28 #include "config-parser.h"
29 #include "lowmem-handler.h"
30 #include "losetup.h"
31
32 #define DEFAULT_ZSWAP_POOL_RATIO (25)
33 #define ZSWAP_FULLNESS_RATIO    0.8
34 #define DEFAULT_ZSWAP_FILE_SIZE MBYTE_TO_BYTE(30)
35
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"
40
41 struct swap_zswap_control {
42         char crypt_type[MAX_TYPE_LENGTH];
43         char swapfile[64];
44         float zpool_ratio;
45         long zswap_file_size;
46         unsigned long zswap_reclaim_bytes;
47         char zpool_type[MAX_TYPE_LENGTH];
48 };
49
50 static struct swap_zswap_control zswap_control = {
51         .crypt_type = "aes",
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,
56         .zpool_type = "zbud",
57 };
58
59 static int swap_zswap_activate(void *data)
60 {
61         struct swap_module_ops *swap = (struct swap_module_ops *)data;
62         int r;
63
64         zswap_control.zswap_reclaim_bytes =
65                         zswap_control.zswap_file_size * ZSWAP_FULLNESS_RATIO;
66
67         r = swap_set_file(zswap_control.swapfile, swap, zswap_control.crypt_type);
68         if (r < 0)
69                 return r;
70
71         r = fwrite_int(ZSWAP_POOL_PERCENT, zswap_control.zpool_ratio);
72         if (r < 0) {
73                 _E("fail to write max_pool_percent: %.2f", zswap_control.zpool_ratio);
74                 return r;
75         }
76
77         r = fwrite_str(ZSWAP_POOL_TYPE, zswap_control.zpool_type);
78         if (r < 0)
79                 _E("fail to change zpool : %s use default", ZSWAP_POOL_TYPE);
80
81         r = fwrite_int(ZSWAP_ENABLED, true);
82         if (r < 0)
83                 _E("fail to enable zswap");
84
85         return 0;
86 }
87
88 static int swap_zswap_reclaim(void *data)
89 {
90         int r;
91         unsigned int swap_size;
92
93         r = fread_uint(ZSWAP_WRITTEN_SIZE, &swap_size);
94         if (r < 0) {
95                 _E("fail to read written swap size");
96                 return r;
97         }
98
99         swap_size <<= PAGE_SHIFT;
100         if (swap_size <= zswap_control.zswap_reclaim_bytes)
101                 return 0;
102
103         /*
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.
108          */
109
110         lowmem_trigger_swap_reclaim(CGROUP_ROOT, swap_size);
111         return -ENOSPC;
112 }
113
114 static int swap_zswap_init(void *data)
115 {
116         struct swap_module_ops *swap = (struct swap_module_ops *)data;
117
118         if (access(ZSWAP_POOL_PERCENT, R_OK) != 0)
119                 return -ENOENT;
120
121         swap->k_size = BYTE_TO_KBYTE(zswap_control.zswap_file_size);
122         return 0;
123 }
124
125 static int swap_zswap_conf(void *data)
126 {
127         struct zswap_conf *zswap_conf = (struct zswap_conf *)data;
128         if (!zswap_conf) {
129                 _E("[DEBUG] Zswap configuration should not be NULL");
130                 return RESOURCED_ERROR_FAIL;
131         }
132
133         if (check_valid_compressor(zswap_conf->type) == RESOURCED_ERROR_NONE)
134                 strncpy(zswap_control.crypt_type, zswap_conf->type, MAX_TYPE_LENGTH-1);
135
136         if (zswap_conf->filesize > 0)
137                 zswap_control.zswap_file_size = zswap_conf->filesize;
138
139         if (zswap_conf->pool_ratio > 0.0)
140                 zswap_control.zpool_ratio = zswap_conf->pool_ratio;
141
142         if (!is_empty(zswap_conf->pool_type))
143                 strncpy(zswap_control.zpool_type, zswap_conf->pool_type, MAX_TYPE_LENGTH-1);
144         else
145                 memset(zswap_control.zpool_type, 0, MAX_TYPE_LENGTH);
146
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);
151
152         return RESOURCED_ERROR_NONE;
153
154 }
155
156 static struct swap_module_ops swap_zswap_ops = {
157         .name = "ZSWAP",
158         .type = SWAP_TYPE_ZSWAP,
159         .path = "",
160         .priority = SWAP_PRI_DISABLE,
161         .k_size = 0,
162         .init = swap_zswap_init,
163         .activate = swap_zswap_activate,
164         .reclaim = swap_zswap_reclaim,
165         .conf = swap_zswap_conf,
166 };
167 SWAP_MODULE_REGISTER(&swap_zswap_ops)