lowmem-monitor: Split up lowmem-monitor feature from lowmem module 93/287593/8
authorSangYoun Kwak <sy.kwak@samsung.com>
Wed, 1 Feb 2023 05:27:53 +0000 (14:27 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Thu, 2 Feb 2023 09:01:00 +0000 (18:01 +0900)
The lowmem-monitor.c was created by extracting the monitor feature from
lowmem.c. (The handler of lowmem pressure)
    * Newly created: lowmem-monitor.c, lowmem-monitor.h
    * "lowmem_monitor_pressure_initialize" function of
      lowmem-monitor.c initializes the handler for lowmem pressure.
    * Symbols used only in lowmem-monitor.c were moved from lowmem.c to
      lowmem-monitor.c.
    * The functions used in both lowmem-monitor.c and lowmem.c remain in
      lowmem.c and were changed to 'non-static' functions.

Change-Id: I26bad0c629b74e8261393d4f7a1d5ce60a9215ab
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
src/resource-limiter/memory/lowmem-monitor.c [new file with mode: 0644]
src/resource-limiter/memory/lowmem-monitor.h [new file with mode: 0644]
src/resource-limiter/memory/lowmem.c
src/resource-limiter/memory/lowmem.h

diff --git a/src/resource-limiter/memory/lowmem-monitor.c b/src/resource-limiter/memory/lowmem-monitor.c
new file mode 100644 (file)
index 0000000..711b8d1
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * resourced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file lowmem-monitor.c
+ * @desc Provides monitor functionalities to detect lowmem state
+ */
+
+#include <unistd.h>
+
+#include "memory-cgroup.h"
+#include "lowmem.h"
+#include "lowmem-monitor.h"
+#include "procfs.h"
+#include "trace.h"
+
+#define LOWMEM_THRES_INIT 0
+
+static char *event_level = MEMCG_DEFAULT_EVENT_LEVEL;
+
+static int lowmem_monitor_pressure_eventfd_read(int fd)
+{
+       unsigned long long dummy_state;
+
+       return read(fd, &dummy_state, sizeof(dummy_state));
+}
+
+static bool lowmem_monitor_pressure_eventfd_handler(int fd, void *data)
+{
+       struct memcg_info *mi;
+       enum cgroup_type type = MEMCG_ROOT;
+       void(*pressure_low_handler)(void) = (void(*)(void))data;
+
+       /* FIXME: probably shouldn't get ignored */
+       if (lowmem_monitor_pressure_eventfd_read(fd) < 0)
+               _E("Failed to read lowmem press event, %m\n");
+
+       for (type = MEMCG_ROOT; type < MEMCG_END; type++) {
+               if (!get_cgroup_tree(type) || !get_memcg_info(type))
+                       continue;
+               mi = get_memcg_info(type);
+               if (fd == mi->evfd) {
+                       /* call low memory handler for this memcg */
+                       if (type == MEMCG_ROOT) {
+                               pressure_low_handler();
+                               return true;
+                       }
+                       else {
+                               _E("Wrong event fd for cgroup %s",
+                                       lowmem_convert_cgroup_type_to_str(type));
+                               return false;
+                       }
+               }
+       }
+
+       return false;
+}
+
+static int lowmem_monitor_pressure_register_eventfd(struct memcg_info *mi,
+                                       void(*pressure_low_handler)(void))
+{
+       int evfd;
+       const char *name = mi->name;
+       static fd_handler_h handler;
+
+       if (mi->threshold_mb[MEM_LEVEL_OOM] == LOWMEM_THRES_INIT)
+               return 0;
+
+       evfd = memcg_set_eventfd(name, MEMCG_EVENTFD_MEMORY_PRESSURE,
+                       event_level);
+
+       if (evfd < 0) {
+               int saved_errno = errno;
+               _E("Failed to register event press fd %s cgroup", name);
+               return -saved_errno;
+       }
+
+       mi->evfd = evfd;
+
+       add_fd_read_handler(NULL, evfd, lowmem_monitor_pressure_eventfd_handler,
+                               pressure_low_handler, NULL, &handler);
+       return 0;
+}
+
+int lowmem_monitor_pressure_initialize(void(*pressure_low_handler)(void))
+{
+       unsigned int i;
+
+       for (i = MEMCG_ROOT; i < MEMCG_END; i++) {
+               if (!get_use_hierarchy(i))
+                       continue;
+
+               lowmem_monitor_pressure_register_eventfd(get_memcg_info(i),
+                               pressure_low_handler);
+       }
+       return RESOURCED_ERROR_NONE;
+}
+
diff --git a/src/resource-limiter/memory/lowmem-monitor.h b/src/resource-limiter/memory/lowmem-monitor.h
new file mode 100644 (file)
index 0000000..6291223
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * resourced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either exmonitor or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @file lowmem-monitor.h
+ * @desc Functions for monitor features.
+ */
+
+#ifndef __LOWMEM_MONITOR_H__
+#define __LOWMEM_MONITOR_H__
+
+int lowmem_monitor_pressure_initialize(void(*pressure_low_handler)(void));
+
+#endif /* __LOWMEM_MONITOR_H__ */
index 64e7a8b..aca7a6b 100644 (file)
@@ -47,6 +47,7 @@
 #include "cgroup.h"
 #include "lowmem.h"
 #include "lowmem-dbus.h"
+#include "lowmem-monitor.h"
 #include "lowmem-system.h"
 #include "lowmem-limit.h"
 #include "lowmem-governor.h"
@@ -70,8 +71,6 @@
 #include "safe-kill.h"
 #include "dedup-common.h"
 
-#define LOWMEM_THRES_INIT                   0
-
 #define MAX_VICTIMS_BETWEEN_CHECK           3
 #define MAX_PROACTIVE_HIGH_VICTIMS          4
 #define FOREGROUND_VICTIMS                  1
@@ -170,8 +169,6 @@ static unsigned proactive_threshold_mb;
 static unsigned proactive_leave_mb;
 static unsigned lmk_start_threshold_mb;
 
-static char *event_level = MEMCG_DEFAULT_EVENT_LEVEL;
-
 /**
  * Resourced Low Memory Killer
  * NOTE: planned to be moved to a separate file.
@@ -295,7 +292,7 @@ static bool oom_popup;
 static bool memcg_swap_status;
 static int fragmentation_size;
 
-static const char *convert_cgroup_type_to_str(int type)
+const char *lowmem_convert_cgroup_type_to_str(int type)
 {
        static const char *type_table[] =
        {"/", "Throttling"};
@@ -1033,7 +1030,7 @@ static void lmk_act(void)
        return;
 }
 
-static void lowmem_trigger_memory_state_action(int mem_state)
+void lowmem_trigger_memory_state_action(int mem_state)
 {
        /*
         * Check if the state we want to set is different from current
@@ -1205,7 +1202,7 @@ static void lowmem_move_memcgroup(int pid, int next_oom_score_adj, struct proc_a
                if(cur_memcg_idx == next_memcg_idx)
                        return;
 
-               _I("app (%s) memory cgroup move from %s to %s", pai->appid, convert_cgroup_type_to_str(cur_memcg_idx), convert_cgroup_type_to_str(next_memcg_idx));
+               _I("app (%s) memory cgroup move from %s to %s", pai->appid, lowmem_convert_cgroup_type_to_str(cur_memcg_idx), lowmem_convert_cgroup_type_to_str(next_memcg_idx));
                cgroup_write_pid_fullpath(mi->name, pid);
                if (next_memcg_idx == MEMCG_THROTTLING)
                        lowmem_swap_memory(get_memcg_info(MEMCG_THROTTLING)->name);
@@ -1265,13 +1262,6 @@ static void lowmem_deactivate_worker(void)
        g_async_queue_unref(lmw.queue);
 }
 
-static int lowmem_press_eventfd_read(int fd)
-{
-       unsigned long long dummy_state;
-
-       return read(fd, &dummy_state, sizeof(dummy_state));
-}
-
 static void lowmem_press_root_cgroup_handler(void)
 {
        static unsigned int prev_available_mb;
@@ -1287,72 +1277,6 @@ static void lowmem_press_root_cgroup_handler(void)
        prev_available_mb = available_mb;
 }
 
-static bool lowmem_press_eventfd_handler(int fd, void *data)
-{
-       struct memcg_info *mi;
-       enum cgroup_type type = MEMCG_ROOT;
-
-       // FIXME: probably shouldn't get ignored
-       if (lowmem_press_eventfd_read(fd) < 0)
-               _E("Failed to read lowmem press event, %m\n");
-
-       for (type = MEMCG_ROOT; type < MEMCG_END; type++) {
-               if (!get_cgroup_tree(type) || !get_memcg_info(type))
-                       continue;
-               mi = get_memcg_info(type);
-               if (fd == mi->evfd) {
-                       /* call low memory handler for this memcg */
-                       if (type == MEMCG_ROOT) {
-                               lowmem_press_root_cgroup_handler();
-                               return true;
-                       }
-                       else {
-                               _E("Wrong event fd for cgroup %s", convert_cgroup_type_to_str(type));
-                               return false;
-                       }
-               }
-       }
-
-       return false;
-}
-
-static int lowmem_press_register_eventfd(struct memcg_info *mi)
-{
-       int evfd;
-       const char *name = mi->name;
-       static fd_handler_h handler;
-
-       if (mi->threshold_mb[MEM_LEVEL_OOM] == LOWMEM_THRES_INIT)
-               return 0;
-
-       evfd = memcg_set_eventfd(name, MEMCG_EVENTFD_MEMORY_PRESSURE,
-                       event_level);
-
-       if (evfd < 0) {
-               int saved_errno = errno;
-               _E("Failed to register event press fd %s cgroup", name);
-               return -saved_errno;
-       }
-
-       mi->evfd = evfd;
-
-       add_fd_read_handler(NULL, evfd, lowmem_press_eventfd_handler, NULL, NULL, &handler);
-       return 0;
-}
-
-static int lowmem_press_setup_eventfd(void)
-{
-       unsigned int i;
-
-       for (i = MEMCG_ROOT; i < MEMCG_END; i++) {
-               if (!get_use_hierarchy(i))
-                       continue;
-
-               lowmem_press_register_eventfd(get_memcg_info(i));
-       }
-       return RESOURCED_ERROR_NONE;
-}
-
 static void lowmem_force_reclaim_cb(struct lowmem_control *ctl)
 {
        lowmem_change_memory_state(MEM_LEVEL_HIGH, 0);
@@ -1584,12 +1508,12 @@ static void print_mem_configs(void)
        /* print info of Memory section */
        for (int cgroup = MEMCG_THROTTLING; cgroup < MEMCG_END; cgroup++) {
                _I("[MEMORY-CGROUP] set memory for cgroup '%s' to %llu bytes",
-                               convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit_bytes);
+                               lowmem_convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit_bytes);
        }
 
        for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) {
                for (int mem_lvl = 0; mem_lvl < MEM_LEVEL_MAX; mem_lvl++) {
-                       _I("[MEMORY-LEVEL] set threshold of %s for memory level '%s' to %u MB", convert_cgroup_type_to_str(cgroup),
+                       _I("[MEMORY-LEVEL] set threshold of %s for memory level '%s' to %u MB", lowmem_convert_cgroup_type_to_str(cgroup),
                                        convert_memstate_to_str(mem_lvl), get_memcg_info(cgroup)->threshold_mb[mem_lvl]);
                }
        }
@@ -1632,7 +1556,8 @@ static int lowmem_init(void)
        }
 
        /* register threshold and event fd */
-       ret = lowmem_press_setup_eventfd();
+       ret = lowmem_monitor_pressure_initialize(
+                       lowmem_press_root_cgroup_handler);
        if (ret) {
                _E("[MEMORY-LIMIT] eventfd setup failed");
                return ret;
index beaa8ba..2dfed7e 100644 (file)
@@ -67,6 +67,9 @@ bool lowmem_fragmentated(void);
 unsigned int lowmem_get_proactive_thres(void);
 void lowmem_change_memory_state(int state, int force);
 
+/* utilities */
+const char *lowmem_convert_cgroup_type_to_str(int type);
+
 /**
  * @desc restore memory cgroup from pid when resourced is restarted
  */