From 3806a149180dcfcc2af65b4c506410600fe59909 Mon Sep 17 00:00:00 2001 From: Unsung Lee Date: Tue, 15 Mar 2022 16:32:51 +0900 Subject: [PATCH] Enhance exception handling of memlimit consider panic on oom case Change-Id: Ie609129858b035b3e2a14a69d1ff834c1b1c3563 Signed-off-by: Unsung Lee --- src/resource-limiter/memory/lowmem-handler.h | 1 - src/resource-limiter/memory/lowmem-limit.c | 57 ++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/resource-limiter/memory/lowmem-handler.h b/src/resource-limiter/memory/lowmem-handler.h index 846a957..02e5b89 100644 --- a/src/resource-limiter/memory/lowmem-handler.h +++ b/src/resource-limiter/memory/lowmem-handler.h @@ -65,7 +65,6 @@ struct memory_limit_event { unsigned int threshold; char *path; enum proc_action action; - GSource *sigterm_timer; int pid; }; diff --git a/src/resource-limiter/memory/lowmem-limit.c b/src/resource-limiter/memory/lowmem-limit.c index 69e1720..3be0115 100644 --- a/src/resource-limiter/memory/lowmem-limit.c +++ b/src/resource-limiter/memory/lowmem-limit.c @@ -51,6 +51,7 @@ #include "fd-handler.h" #include "dbus-handler.h" #include "safe-kill.h" +#include "file-helper.h" #define MEM_CONF_FILE RD_CONFIG_FILE(limiter) #define MEMLIMIT_CONFIG_SECTION "MemLimit" @@ -223,7 +224,6 @@ static gboolean liveness_check_cb(gpointer data) mle_timer_init: mle->pid = -1; - mle->sigterm_timer = NULL; timer_out: return G_SOURCE_REMOVE; } @@ -232,7 +232,7 @@ static bool memory_action_cb(int fd, void *data) { int result; pid_t main_pid; - uint32_t usage, anon_usage, max_mem; + uint32_t usage, max_mem; uint64_t dummy_efd; char *cg_dir = (char *)data; struct memory_limit_event *mle; @@ -277,13 +277,13 @@ static bool memory_action_cb(int fd, void *data) goto remove_mle; } - anon_usage = mem_stat->value[CGROUP_MEMORY_STAT_RSS] + +/* anon_usage = mem_stat->value[CGROUP_MEMORY_STAT_RSS] + mem_stat->value[CGROUP_MEMORY_STAT_SWAP]; if (anon_usage < mle->threshold) { _D("[DEBUG] (%s) cgroup escaped low memory status. usage(%d), anon usage (%d), threshold(%d)", cg_dir, usage, anon_usage, mle->threshold); return true; - } + }*/ switch (mle->action) { case PROC_ACTION_BROADCAST: @@ -309,10 +309,11 @@ static bool memory_action_cb(int fd, void *data) } safe_kill(main_pid, SIGTERM); - if (mle->sigterm_timer == NULL) { + if (mle->pid == -1) { mle->pid = main_pid; g_timeout_add_seconds(2, liveness_check_cb, mle); } + break; default: _E("[DEBUG] Unkown action of memory threshold"); @@ -325,12 +326,33 @@ remove_mle: return false; } +static void set_limit_in_bytes(const char *dir, unsigned int limit) +{ + int error; + unsigned int prev; + + error = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev); + if (error) { + _E("[DEBUG] Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir); + return; + } + + if (prev > (limit * 1.2)) { + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2)); + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2)); + } + else { + cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2)); + cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2)); + } +} + int lowmem_reassign_limit(const char *dir, unsigned int limit, enum proc_action action) { int fd; int error; - unsigned int prev; + unsigned int poo; fd_handler_h fdh = NULL; gpointer hash_entry; struct memory_limit_event *mle = NULL; @@ -358,19 +380,21 @@ int lowmem_reassign_limit(const char *dir, } } - error = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev); + error = fread_uint("/proc/sys/vm/panic_on_oom", &poo); if (error) { - _E("[DEBUG] Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir); + _E("[DEBUG] Failed to get %s from %s", "/proc/sys/vm/panic_on_oom", dir); return RESOURCED_ERROR_FAIL; } - if (prev > (limit * 1.2)) { - cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2)); - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2)); + /* If panic_on_oom is true (> 1), oom should be disabled */ + if (poo != 0) { + _I("%s's value is %d. That is, kernel panic will be inevitable, when oom happens", "proc/sys/vm/panic_on_oom", poo); + error = cgroup_write_node_uint32(dir, MEMCG_OOM_CONTROL, 1); + if (!error) + set_limit_in_bytes(dir, limit); } else { - cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2)); - cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2)); + set_limit_in_bytes(dir, limit); } snprintf(buf, sizeof(buf), "%d", limit); @@ -398,7 +422,6 @@ int lowmem_reassign_limit(const char *dir, mle->action = action; mle->threshold = limit; mle->pid = -1; - mle->sigterm_timer = NULL; add_fd_read_handler(fd, memory_action_cb, mle->path, NULL, &fdh); mle->fdh = fdh; g_hash_table_insert(memory_limit_hash, (gpointer)mle->path, @@ -496,7 +519,11 @@ void lowmem_limit_set_system_service(pid_t pid, unsigned int limit, return; } - lowmem_reassign_limit(path, limit, action); + result = lowmem_reassign_limit(path, limit, action); + if (result < 0) { + _W("Failed to reassign limit for %s", path); + return; + } result = cgroup_write_node_uint32(path, MEMCG_MOVE_CHARGE, 3U); if (result < 0) -- 2.7.4