lowmem-monitor: Rename to lowmem-monitor-vmpressure
[platform/core/system/resourced.git] / src / resource-limiter / memory / lowmem-monitor-vmpressure.c
1 /**
2  * resourced
3  *
4  * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
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 /**
20  * @file lowmem-monitor.c
21  * @desc Provides monitor functionalities to detect lowmem state
22  */
23
24 #include <unistd.h>
25
26 #include "memory-cgroup.h"
27 #include "lowmem.h"
28 #include "procfs.h"
29 #include "trace.h"
30 #include "module.h"
31
32 #define LOWMEM_THRES_INIT 0
33
34 static char *event_level = MEMCG_DEFAULT_EVENT_LEVEL;
35
36 static int lowmem_monitor_pressure_eventfd_read(int fd)
37 {
38         unsigned long long dummy_state;
39
40         return read(fd, &dummy_state, sizeof(dummy_state));
41 }
42
43 static void lowmem_monitor_raise_lowmem_event(void)
44 {
45         static unsigned int prev_available_mb;
46         unsigned int available_mb;
47         int mem_state;
48
49         available_mb = proc_get_mem_available();
50         if (prev_available_mb == available_mb)
51                 return;
52
53         mem_state = lowmem_check_mem_state(available_mb);
54         lowmem_trigger_memory_state_action(mem_state);
55         prev_available_mb = available_mb;
56 }
57
58 static bool lowmem_monitor_pressure_eventfd_handler(int fd, void *data)
59 {
60         struct memcg_info *mi;
61         enum cgroup_type type = MEMCG_ROOT;
62
63         /* FIXME: probably shouldn't get ignored */
64         if (lowmem_monitor_pressure_eventfd_read(fd) < 0)
65                 _E("Failed to read lowmem press event, %m\n");
66
67         for (type = MEMCG_ROOT; type < MEMCG_END; type++) {
68                 if (!get_cgroup_tree(type) || !get_memcg_info(type))
69                         continue;
70                 mi = get_memcg_info(type);
71                 if (fd == mi->evfd) {
72                         /* call low memory handler for this memcg */
73                         if (type == MEMCG_ROOT) {
74                                 lowmem_monitor_raise_lowmem_event();
75                                 return true;
76                         }
77                         else {
78                                 _E("Wrong event fd for cgroup %s",
79                                         lowmem_convert_cgroup_type_to_str(type));
80                                 return false;
81                         }
82                 }
83         }
84
85         return false;
86 }
87
88 static int lowmem_monitor_pressure_register_eventfd(struct memcg_info *mi)
89 {
90         int evfd;
91         const char *name = mi->name;
92         static fd_handler_h handler;
93
94         if (mi->threshold_mb[MEM_LEVEL_OOM] == LOWMEM_THRES_INIT)
95                 return 0;
96
97         evfd = memcg_set_eventfd(name, MEMCG_EVENTFD_MEMORY_PRESSURE,
98                         event_level);
99
100         if (evfd < 0) {
101                 int saved_errno = errno;
102                 _E("Failed to register event press fd %s cgroup", name);
103                 return -saved_errno;
104         }
105
106         mi->evfd = evfd;
107
108         add_fd_read_handler(NULL, evfd, lowmem_monitor_pressure_eventfd_handler,
109                                 NULL, NULL, &handler);
110         return 0;
111 }
112
113 static int lowmem_monitor_initialize(void *data)
114 {
115         unsigned int i;
116
117         for (i = MEMCG_ROOT; i < MEMCG_END; i++) {
118                 if (!get_use_hierarchy(i))
119                         continue;
120
121                 lowmem_monitor_pressure_register_eventfd(get_memcg_info(i));
122         }
123         return RESOURCED_ERROR_NONE;
124 }
125
126 static int lowmem_monitor_finalize(void *data)
127 {
128         return RESOURCED_ERROR_NONE;
129 }
130
131 static struct module_ops lowmem_monitor_vmpressure_modules_ops = {
132         .priority       = MODULE_PRIORITY_INITIAL,
133         .name           = "lowmem-monitor-vmpressure",
134         .init           = lowmem_monitor_initialize,
135         .exit           = lowmem_monitor_finalize,
136 };
137
138 MODULE_REGISTER(&lowmem_monitor_vmpressure_modules_ops)