From: Unsung Date: Thu, 10 Oct 2024 09:04:42 +0000 (+0900) Subject: memory-cgroup: Add getter to replace direct access to memcg info X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d53b41f0b2ba84d0157216b5b05e65357dba0e6b;p=platform%2Fcore%2Fsystem%2Fresourced.git memory-cgroup: Add getter to replace direct access to memcg info Add getter functions to block direct access to memcg info structure. This is because it may cause incorrect memory access by null pointer. Change-Id: I61d2d33988b9ab408a8eaa628a7832bb4551b0f9 Signed-off-by: Unsung Lee --- diff --git a/src/common/cgroup/memory-cgroup.c b/src/common/cgroup/memory-cgroup.c index 93fc69b9..409fa49a 100644 --- a/src/common/cgroup/memory-cgroup.c +++ b/src/common/cgroup/memory-cgroup.c @@ -760,3 +760,139 @@ enum memcg_limit_trigger get_memcg_limit_trigger(void) { return g_limit_trigger; } + +int memory_cgroup_get_memcg_info_name(enum cgroup_type cgroup_type, char *name, int maxsize) +{ + struct memcg_info *memcg_info; + + if (!name) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + if (strlen(memcg_info->name) + 1 > maxsize) + return RESOURCED_ERROR_INVALID_PARAMETER; + + strncpy(name, memcg_info->name, maxsize - 1); + + return RESOURCED_ERROR_NONE; +} + +int memory_cgroup_get_memcg_info_swappiness(enum cgroup_type cgroup_type, int *swappiness) +{ + struct memcg_info *memcg_info; + + if (!swappiness) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *swappiness = memcg_info->swappiness; + + return RESOURCED_ERROR_NONE; +} + +int memory_cgroup_get_memcg_info_evfd(enum cgroup_type cgroup_type, int *evfd) +{ + struct memcg_info *memcg_info; + + if (!evfd) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *evfd = memcg_info->evfd; + + return RESOURCED_ERROR_NONE; +} + +int memory_cgroup_get_memcg_info_limit_bytes(enum cgroup_type cgroup_type, + uint64_t *limit_bytes) +{ + struct memcg_info *memcg_info; + + if (!limit_bytes) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *limit_bytes = memcg_info->limit_bytes; + + return RESOURCED_ERROR_NONE; +} + +int memory_cgroup_get_memcg_info_limit_ratio(enum cgroup_type cgroup_type, + float *limit_ratio) +{ + struct memcg_info *memcg_info; + + if (!limit_ratio) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *limit_ratio = memcg_info->limit_ratio; + + return RESOURCED_ERROR_NONE; +} + +static bool is_valid_mem_level(int mem_level) +{ + switch(mem_level) { + case MEM_LEVEL_HIGH: + case MEM_LEVEL_MEDIUM: + case MEM_LEVEL_LOW: + case MEM_LEVEL_CRITICAL: + case MEM_LEVEL_OOM: + return true; + default: + return false; + } +} + +int memory_cgroup_get_memcg_info_threshold_mb(enum cgroup_type cgroup_type, + int mem_level, unsigned int *threshold_mb) +{ + struct memcg_info *memcg_info; + + if (!threshold_mb) + return RESOURCED_ERROR_INVALID_PARAMETER; + + if (!is_valid_mem_level(mem_level)) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *threshold_mb = memcg_info->threshold_mb[mem_level]; + + return RESOURCED_ERROR_NONE; +} + +int memory_cgroup_get_memcg_info_threshold_leave_mb(enum cgroup_type cgroup_type, + unsigned int *threshold_leave_mb) +{ + struct memcg_info *memcg_info; + + if (!threshold_leave_mb) + return RESOURCED_ERROR_INVALID_PARAMETER; + + memcg_info = get_memcg_info(cgroup_type); + if (!memcg_info) + return RESOURCED_ERROR_FAIL; + + *threshold_leave_mb = memcg_info->threshold_leave_mb; + + return RESOURCED_ERROR_NONE; +} diff --git a/src/common/cgroup/memory-cgroup.h b/src/common/cgroup/memory-cgroup.h index 03e4b99f..779bd15b 100644 --- a/src/common/cgroup/memory-cgroup.h +++ b/src/common/cgroup/memory-cgroup.h @@ -293,6 +293,18 @@ struct cgroup *get_cgroup_tree(int idx); void set_memcg_limit_trigger(enum memcg_limit_trigger limit_trigger); enum memcg_limit_trigger get_memcg_limit_trigger(void); +int memory_cgroup_get_memcg_info_name(enum cgroup_type cgroup_type, char *name, int maxsize); +int memory_cgroup_get_memcg_info_swappiness(enum cgroup_type cgroup_type, int *swappiness); +int memory_cgroup_get_memcg_info_evfd(enum cgroup_type cgroup_type, int *evfd); +int memory_cgroup_get_memcg_info_limit_bytes(enum cgroup_type cgroup_type, + uint64_t *limit_bytes); +int memory_cgroup_get_memcg_info_limit_ratio(enum cgroup_type cgroup_type, + float *limit_ratio); +int memory_cgroup_get_memcg_info_threshold_mb(enum cgroup_type cgroup_type, + int mem_level, unsigned int *threshold_mb); +int memory_cgroup_get_memcg_info_threshold_leave_mb(enum cgroup_type cgroup_type, + unsigned int *threshold_leave_mb); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/resource-limiter/memory/lowmem-controller.c b/src/resource-limiter/memory/lowmem-controller.c index 6065e5f6..df7721f2 100644 --- a/src/resource-limiter/memory/lowmem-controller.c +++ b/src/resource-limiter/memory/lowmem-controller.c @@ -278,6 +278,8 @@ static void lowmem_swap_memory(char *path) /* The services cannot call this function but the apps can. */ unsigned int available_mb; unsigned int cur_mem_state; + unsigned int threshold_mb = 0; + int ret = RESOURCED_ERROR_NONE; cur_mem_state = lowmem_get_lowmem_state(); if (cur_mem_state == MEM_LEVEL_HIGH) @@ -286,9 +288,15 @@ static void lowmem_swap_memory(char *path) if (swap_get_state() != SWAP_ON) return; + ret = memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, MEM_LEVEL_LOW, + &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + return; + } + available_mb = proc_get_mem_available(); - if (cur_mem_state != MEM_LEVEL_LOW && - available_mb <= get_root_memcg_info()->threshold_mb[MEM_LEVEL_LOW]) + if (cur_mem_state != MEM_LEVEL_LOW && available_mb <= threshold_mb) swap_activate_act(); resourced_notify(RESOURCED_NOTIFIER_SWAP_START, path); @@ -315,6 +323,8 @@ static void lowmem_move_memcgroup(int pid, int next_oom_score_adj, struct proc_a } if (pai->main_pid == pid) { + char memcg_info_name[PATH_MAX] = {}; + /* parent pid */ cur_oom_score_adj = pai->memory.oom_score_adj; cur_memcg_idx = cgroup_get_type(cur_oom_score_adj); @@ -351,8 +361,10 @@ static void lowmem_move_memcgroup(int pid, int next_oom_score_adj, struct proc_a if(cur_memcg_idx == next_memcg_idx) return; - if (next_memcg_idx == MEMCG_BACKGROUND_LRU) - lowmem_swap_memory(get_memcg_info(MEMCG_BACKGROUND_LRU)->name); + if (next_memcg_idx == MEMCG_BACKGROUND_LRU && + memory_cgroup_get_memcg_info_name(MEMCG_BACKGROUND_LRU, memcg_info_name, + sizeof memcg_info_name) == RESOURCED_ERROR_NONE) + lowmem_swap_memory(memcg_info_name); } else { /* child pid */ switch (next_memcg_idx) { @@ -414,12 +426,21 @@ static int lowmem_control_handler(void *data) static int lowmem_bg_reclaim_handler(void *data) { + char memcg_info_name[PATH_MAX] = {}; + int ret = RESOURCED_ERROR_NONE; + if (swap_get_state() != SWAP_ON) return RESOURCED_ERROR_NONE; if (!is_bg_reclaim_supported()) return RESOURCED_ERROR_NONE; + ret = memory_cgroup_get_memcg_info_name(MEMCG_BACKGROUND_MRU, memcg_info_name, sizeof memcg_info_name); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get name from memcg info: ret(%d)", ret); + return RESOURCED_ERROR_FAIL; + } + /* * Proactively reclaiming memory used by long-lived background processes * (such as widget instances) may be efficient on devices with limited @@ -428,7 +449,7 @@ static int lowmem_bg_reclaim_handler(void *data) * impact on the user experience. */ resourced_notify(RESOURCED_NOTIFIER_SWAP_START, - get_memcg_info(MEMCG_BACKGROUND_MRU)->name); + memcg_info_name); return RESOURCED_ERROR_NONE; } @@ -446,6 +467,7 @@ static void medium_cb(struct lowmem_control *ctl) static int high_mem_control(void *data) { int ret, status; + enum cgroup_type cgroup_type = MEMCG_BACKGROUND_LRU; ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); if (ret) @@ -459,8 +481,7 @@ static int high_mem_control(void *data) lowmem_change_lowmem_state(MEM_LEVEL_HIGH); if (swap_get_state() == SWAP_ON && lowmem_get_memcg_swap_status()) { - resourced_notify(RESOURCED_NOTIFIER_SWAP_UNSET_LIMIT, - get_memcg_info(MEMCG_BACKGROUND_LRU)); + resourced_notify(RESOURCED_NOTIFIER_SWAP_UNSET_LIMIT, &cgroup_type); lowmem_set_memcg_swap_status(false); } if (proc_get_freezer_status() == CGROUP_FREEZER_PAUSED) diff --git a/src/resource-limiter/memory/lowmem-dbus.c b/src/resource-limiter/memory/lowmem-dbus.c index 3d8beaf1..fe6dfc7d 100644 --- a/src/resource-limiter/memory/lowmem-dbus.c +++ b/src/resource-limiter/memory/lowmem-dbus.c @@ -84,12 +84,20 @@ static void lowmem_dbus_set_platform(GVariant *params) { pid_t pid = 0; const char *const gtype = "(i)"; + char memcg_info_name[PATH_MAX] = {}; + int ret = RESOURCED_ERROR_NONE; ret_if_gvariant_type_mismatch(params, gtype); g_variant_get(params, gtype, &pid); ret_unless(pid > 0); - lowmem_trigger_swap(pid, get_memcg_info(MEMCG_BACKGROUND_LRU)->name, true); + ret = memory_cgroup_get_memcg_info_name(MEMCG_BACKGROUND_LRU, memcg_info_name, sizeof memcg_info_name); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get name from memcg info: ret(%d)", ret); + return; + } + + lowmem_trigger_swap(pid, memcg_info_name, true); } static void lowmem_dbus_set_memlimit(GVariant *params) diff --git a/src/resource-limiter/memory/lowmem-monitor-vmpressure.c b/src/resource-limiter/memory/lowmem-monitor-vmpressure.c index 8867ca1e..9c01cd6a 100644 --- a/src/resource-limiter/memory/lowmem-monitor-vmpressure.c +++ b/src/resource-limiter/memory/lowmem-monitor-vmpressure.c @@ -57,18 +57,21 @@ static void lowmem_monitor_raise_lowmem_event(void) static bool lowmem_monitor_pressure_eventfd_handler(int fd, void *data) { - struct memcg_info *mi; enum cgroup_type type = MEMCG_ROOT; + int evfd = 0; /* 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)) + if (!get_cgroup_tree(type)) continue; - mi = get_memcg_info(type); - if (fd == mi->evfd) { + + if (memory_cgroup_get_memcg_info_evfd(type, &evfd) != RESOURCED_ERROR_NONE) + continue; + + if (fd == evfd) { /* call low memory handler for this memcg */ if (type == MEMCG_ROOT) { lowmem_monitor_raise_lowmem_event(); @@ -85,13 +88,30 @@ static bool lowmem_monitor_pressure_eventfd_handler(int fd, void *data) return false; } -static int lowmem_monitor_pressure_register_eventfd(struct memcg_info *mi) +static int lowmem_monitor_pressure_register_eventfd(enum cgroup_type cgroup_type, + struct memcg_info *mi) { int evfd; - const char *name = mi->name; + char name[PATH_MAX] = {}; static fd_handler_h handler; + unsigned int threshold_mb = 0; + int ret = RESOURCED_ERROR_NONE; + + ret = memory_cgroup_get_memcg_info_name(cgroup_type, name, + sizeof name); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info name: ret (%d)", ret); + return RESOURCED_ERROR_FAIL; + } + + ret = memory_cgroup_get_memcg_info_threshold_mb(cgroup_type, MEM_LEVEL_OOM, + &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + return RESOURCED_ERROR_FAIL; + } - if (mi->threshold_mb[MEM_LEVEL_OOM] == LOWMEM_THRES_INIT) + if (threshold_mb == LOWMEM_THRES_INIT) return 0; evfd = memcg_set_eventfd(name, MEMCG_EVENTFD_MEMORY_PRESSURE, @@ -122,7 +142,7 @@ int lowmem_monitor_vmpressure_initialize(void *data) if (!get_use_hierarchy(i)) continue; - lowmem_monitor_pressure_register_eventfd(get_memcg_info(i)); + lowmem_monitor_pressure_register_eventfd(i, get_memcg_info(i)); } return RESOURCED_ERROR_NONE; } diff --git a/src/resource-limiter/memory/lowmem.c b/src/resource-limiter/memory/lowmem.c index 5aad04f3..4a15c340 100644 --- a/src/resource-limiter/memory/lowmem.c +++ b/src/resource-limiter/memory/lowmem.c @@ -990,6 +990,8 @@ static void lowmem_handle_request(struct lowmem_control *ctl, int lmk_try_count) unsigned int reclaim_size_mb, shortfall_mb = 0; enum syscommon_resourced_memory_lmk_oom_level oom_level = ctl->oom_level; + unsigned int threshold_mb = 0; + int ret = RESOURCED_ERROR_NONE; available_mb = proc_get_mem_available(); reclaim_size_mb = ctl->size_mb > available_mb /* MB */ @@ -1005,7 +1007,13 @@ retry: if (calculate_range_of_oom(oom_level, &start_oom, &end_oom)) goto done; - lmk_start_threshold_mb = get_root_memcg_info()->threshold_mb[MEM_LEVEL_OOM]; + ret = memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, MEM_LEVEL_OOM, &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + goto done; + } + + lmk_start_threshold_mb = threshold_mb; shortfall_mb = is_memory_recovered(&available_mb, ctl->size_mb); if (!shortfall_mb || !reclaim_size_mb) { @@ -1167,8 +1175,17 @@ unsigned int lowmem_get_lowmem_state() } void lowmem_change_lowmem_state(unsigned int mem_state) { + unsigned int threshold_mb = 0; + int ret = RESOURCED_ERROR_NONE; + cur_mem_state = mem_state; - lmk_start_threshold_mb = get_root_memcg_info()->threshold_mb[MEM_LEVEL_OOM]; + + ret = memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, MEM_LEVEL_OOM, &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + return; + } + lmk_start_threshold_mb = threshold_mb; resourced_notify(RESOURCED_NOTIFIER_MEM_LEVEL_CHANGED, (void *)&cur_mem_state); @@ -1243,9 +1260,14 @@ void lowmem_trigger_memory_state_action(int mem_state) unsigned int lowmem_check_mem_state(unsigned int available_mb) { int mem_state; + unsigned int threshold_mb = 0; + for (mem_state = MEM_LEVEL_MAX - 1; mem_state > MEM_LEVEL_HIGH; mem_state--) { - if (mem_state != MEM_LEVEL_OOM && - available_mb <= get_root_memcg_info()->threshold_mb[mem_state]) + if (memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, mem_state, + &threshold_mb) != RESOURCED_ERROR_NONE) + continue; + + if (mem_state != MEM_LEVEL_OOM && available_mb <= threshold_mb) break; else if (mem_state == MEM_LEVEL_OOM && available_mb <= lmk_start_threshold_mb) break; @@ -1400,15 +1422,25 @@ int lowmem_trigger_reclaim(int flags, int victims, int threshold_mb) { struct lowmem_control *ctl = LOWMEM_NEW_REQUEST(); + unsigned int threshold_leave_mb = 0; + int ret = RESOURCED_ERROR_NONE; if (!ctl) return -ENOMEM; + ret = memory_cgroup_get_memcg_info_threshold_leave_mb(MEMCG_ROOT, + &threshold_leave_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold leave: ret (%d)", ret); + LOWMEM_DESTROY_REQUEST(ctl); + return -EINVAL; + } + flags |= OOM_FORCE | OOM_IN_DEPTH | OOM_SINGLE_SHOT; victims = victims > 0 ? victims : MAX_MEMORY_CGROUP_VICTIMS; oom_level = oom_level > OOM_LEVEL_BACKGROUND_LEAST_RECENTLY_USED ? oom_level : OOM_LEVEL_BACKGROUND_LEAST_RECENTLY_USED; - threshold_mb = threshold_mb > 0 ? threshold_mb : get_root_memcg_info()->threshold_leave_mb; + threshold_mb = threshold_mb > 0 ? threshold_mb : threshold_leave_mb; lowmem_change_memory_state(MEM_LEVEL_CRITICAL, 1); LOWMEM_SET_REQUEST(ctl, flags, @@ -1445,11 +1477,20 @@ void lowmem_trigger_swap_reclaim( unsigned long long swap_size_bytes) { int size_mb, victims; + unsigned int threshold_leave_mb = 0; + int ret = RESOURCED_ERROR_NONE; victims = num_max_victims > MAX_PROACTIVE_HIGH_VICTIMS ? MAX_PROACTIVE_HIGH_VICTIMS : num_max_victims; - size_mb = get_root_memcg_info()->threshold_leave_mb + BYTE_TO_MBYTE(swap_size_bytes); + ret = memory_cgroup_get_memcg_info_threshold_leave_mb(MEMCG_ROOT, + &threshold_leave_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold leave: ret (%d)", ret); + return; + } + + size_mb = threshold_leave_mb + BYTE_TO_MBYTE(swap_size_bytes); lowmem_trigger_reclaim(0, victims, oom_level, size_mb); } @@ -1480,12 +1521,20 @@ static void lowmem_proactive_oom_killer(int flags, char *appid) { unsigned int before_mb; int victims; + unsigned int threshold_mb = 0; + int ret = RESOURCED_ERROR_NONE; before_mb = proc_get_mem_available(); + ret = memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, MEM_LEVEL_OOM, + &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + return; + } + /* If memory state is medium or normal, just return and kill in oom killer */ - if (before_mb < get_root_memcg_info()->threshold_mb[MEM_LEVEL_OOM] || - before_mb > proactive_leave_mb) + if (before_mb < threshold_mb || before_mb > proactive_leave_mb) return; victims = num_max_victims > MAX_PROACTIVE_HIGH_VICTIMS @@ -1580,10 +1629,45 @@ static inline int calculate_threshold_size(double ratio) return BYTE_TO_MBYTE(size_bytes); } +static int load_lmk_threshold_config(int mem_level) +{ + unsigned int threshold_mb = 0; + unsigned int threshold_leave_mb = 0; + int ret = RESOURCED_ERROR_NONE; + + switch (mem_level) { + case MEM_LEVEL_OOM: + break; + default: + return RESOURCED_ERROR_NONE; + } + + ret = memory_cgroup_get_memcg_info_threshold_mb(MEMCG_ROOT, mem_level, + &threshold_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold: ret (%d)", ret); + return RESOURCED_ERROR_FAIL; + } + + ret = memory_cgroup_get_memcg_info_threshold_leave_mb(MEMCG_ROOT, + &threshold_leave_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold leave: ret (%d)", ret); + return RESOURCED_ERROR_FAIL; + } + + memcg_set_leave_threshold(MEMCG_ROOT, threshold_mb * 1.5); + proactive_threshold_mb = threshold_leave_mb; + proactive_leave_mb = proactive_threshold_mb * 1.5; + + return RESOURCED_ERROR_NONE; +} + static void load_configs(void) { struct memcg_conf *memcg_conf = get_memcg_conf(); struct reclaim_conf *reclaim_conf = config_get_reclaim_conf(); + int ret = RESOURCED_ERROR_NONE; /* set MemoryGroupLimit section */ for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) { @@ -1599,24 +1683,23 @@ static void load_configs(void) memcg_set_threshold(MEMCG_ROOT, lvl, calculate_threshold_size(memcg_conf->threshold[lvl].threshold)); - if (lvl == MEM_LEVEL_OOM) { - memcg_set_leave_threshold(MEMCG_ROOT, - get_memcg_info(MEMCG_ROOT)->threshold_mb[lvl] * 1.5); - proactive_threshold_mb = get_memcg_info(MEMCG_ROOT)->threshold_leave_mb; - proactive_leave_mb = proactive_threshold_mb * 1.5; + ret = load_lmk_threshold_config(lvl); + if (ret != RESOURCED_ERROR_NONE) + { + _E("Failed to load lmk threshold config: ret (%d)", ret); + return; } } else if (memcg_conf->threshold[lvl].threshold > 0) { memcg_set_threshold(MEMCG_ROOT, lvl, memcg_conf->threshold[lvl].threshold); - if (lvl == MEM_LEVEL_OOM) { - memcg_set_leave_threshold(MEMCG_ROOT, - get_memcg_info(MEMCG_ROOT)->threshold_mb[lvl] * 1.5); - proactive_threshold_mb = get_memcg_info(MEMCG_ROOT)->threshold_leave_mb; - proactive_leave_mb = proactive_threshold_mb * 1.5; + ret = load_lmk_threshold_config(lvl); + if (ret != RESOURCED_ERROR_NONE) + { + _E("Failed to load lmk threshold config: ret (%d)", ret); + return; } - } } @@ -1653,23 +1736,51 @@ free_memcg_conf: free_memcg_conf(); } +static int print_memcg_info_threshold_of_all_levels(enum cgroup_type cgroup_type) +{ + for (int mem_level = 0; mem_level < MEM_LEVEL_MAX; mem_level++) { + unsigned int threshold_mb = 0; + + if (memory_cgroup_get_memcg_info_threshold_mb(cgroup_type, mem_level, + &threshold_mb) != RESOURCED_ERROR_NONE) + continue; + + _I("[MEMORY-LEVEL] Set threshold of %s for memory level '%s' to %u MB", + lowmem_convert_cgroup_type_to_str(cgroup_type), + convert_memstate_to_str(mem_level), threshold_mb); + } + + return RESOURCED_ERROR_NONE; +} + static void print_mem_configs(void) { + unsigned int threshold_leave_mb = 0; + int ret = RESOURCED_ERROR_NONE; + + ret = memory_cgroup_get_memcg_info_threshold_leave_mb(MEMCG_ROOT, + &threshold_leave_mb); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info threshold leave: ret (%d)", ret); + return; + } + /* print info of Memory section */ for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) { + uint64_t limit_bytes = 0; + if (memory_cgroup_get_memcg_info_limit_bytes(cgroup, &limit_bytes) + != RESOURCED_ERROR_NONE) + continue; + _I("[MEMORY-CGROUP] set memory for cgroup '%s' to %llu bytes", - lowmem_convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit_bytes); + lowmem_convert_cgroup_type_to_str(cgroup), (unsigned long long)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", lowmem_convert_cgroup_type_to_str(cgroup), - convert_memstate_to_str(mem_lvl), get_memcg_info(cgroup)->threshold_mb[mem_lvl]); - } - } + for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) + print_memcg_info_threshold_of_all_levels(cgroup); _I("[LMK] set number of max victims as %d", num_max_victims); - _I("[LMK] set threshold leave to %u MB", get_root_memcg_info()->threshold_leave_mb); + _I("[LMK] set threshold leave to %u MB", threshold_leave_mb); _I("[LMK] set proactive threshold to %u MB", proactive_threshold_mb); _I("[LMK] set proactive low memory killer leave to %u MB", proactive_leave_mb); diff --git a/src/resource-optimizer/memory/swap/swap.c b/src/resource-optimizer/memory/swap/swap.c index cbb7fd72..f726f0a4 100644 --- a/src/resource-optimizer/memory/swap/swap.c +++ b/src/resource-optimizer/memory/swap/swap.c @@ -805,32 +805,49 @@ static int swap_compact_handler(void *data) static int swap_cgroup_reset_limit(void *data) { int ret; - struct memcg_info *mi = (struct memcg_info *)data; + enum cgroup_type *cgroup_type = (enum cgroup_type*)data; + char memcg_info_name[PATH_MAX] = {}; + float limit_ratio = 0.0; + uint64_t limit_bytes = 0; + + ret = memory_cgroup_get_memcg_info_name(*cgroup_type, memcg_info_name, + sizeof memcg_info_name); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info name: ret (%d)", ret); + return ret; + } - if (!mi) { - _E("[SWAP] memory cgroup information is NULL"); - return RESOURCED_ERROR_INVALID_PARAMETER; + ret = memory_cgroup_get_memcg_info_limit_ratio(*cgroup_type, &limit_ratio); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info limit ratio: ret (%d)", ret); + return ret; + } + + ret = memory_cgroup_get_memcg_info_limit_bytes(*cgroup_type, &limit_bytes); + if (ret != RESOURCED_ERROR_NONE) { + _E("Failed to get memcg info limit bytes: ret (%d)", ret); + return ret; } if (swap_node == SWAP_NODE_FORCE_RECLAIM) return RESOURCED_ERROR_NONE; - if (mi->limit_ratio == MEMCG_NO_LIMIT) { + if (limit_ratio == MEMCG_NO_LIMIT) { if (memcg_memsw_is_supported()) { - ret = cgroup_write_node_int32(mi->name, MEMCG_SWAP_LIMIT_BYTE, -1); + ret = cgroup_write_node_int32(memcg_info_name, MEMCG_SWAP_LIMIT_BYTE, -1); if (ret != RESOURCED_ERROR_NONE) goto limit_update_out; } - ret = cgroup_write_node_int32(mi->name, MEMCG_LIMIT_BYTE, -1); + ret = cgroup_write_node_int32(memcg_info_name, MEMCG_LIMIT_BYTE, -1); } else - ret = check_oom_and_set_limit(mi->name, mi->limit_bytes); + ret = check_oom_and_set_limit(memcg_info_name, limit_bytes); limit_update_out: if (ret != RESOURCED_ERROR_NONE) - _E("[SWAP] Failed to change hard limit of %s cgroup to -1", mi->name); + _E("[SWAP] Failed to change hard limit of %s cgroup to -1", memcg_info_name); else - _D("[SWAP] changed hard limit of %s cgroup to -1", mi->name); + _D("[SWAP] changed hard limit of %s cgroup to -1", memcg_info_name); return ret; } @@ -899,6 +916,8 @@ static int swap_parse_config_file(void) if (swap_conf->swappiness[MEMCG_BACKGROUND_LRU] >= 0 && swap_conf->swappiness[MEMCG_BACKGROUND_LRU] <= 100) { + int swappiness = 0; + memcg_info_set_swappiness(get_memcg_info(MEMCG_BACKGROUND_LRU), swap_conf->swappiness[MEMCG_BACKGROUND_LRU]); r = memcg_write_optimizer_params(MEMCG_BACKGROUND_LRU); @@ -907,8 +926,10 @@ static int swap_parse_config_file(void) goto free_swap_conf; } - _I("[SWAP] cgroup (%s) swapiness = %d", MEMCG_BACKGROUND_LRU_NAME, - get_memcg_info(MEMCG_BACKGROUND_LRU)->swappiness); + r = memory_cgroup_get_memcg_info_swappiness(MEMCG_BACKGROUND_LRU, &swappiness); + if (r == RESOURCED_ERROR_NONE) + _I("[SWAP] cgroup (%s) swapiness = %d", MEMCG_BACKGROUND_LRU_NAME, + swappiness); } gslist_for_each_item(iter, swap_module) {