memory-cgroup: Add getter to replace direct access to memcg info 85/320485/2
authorUnsung <unsung.lee@samsung.com>
Thu, 10 Oct 2024 09:04:42 +0000 (18:04 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Fri, 22 Nov 2024 09:52:50 +0000 (18:52 +0900)
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 <unsung.lee@samsung.com>
src/common/cgroup/memory-cgroup.c
src/common/cgroup/memory-cgroup.h
src/resource-limiter/memory/lowmem-controller.c
src/resource-limiter/memory/lowmem-dbus.c
src/resource-limiter/memory/lowmem-monitor-vmpressure.c
src/resource-limiter/memory/lowmem.c
src/resource-optimizer/memory/swap/swap.c

index 93fc69b972bf56e3f5886df9405fe175dca92c27..409fa49a31ad5d35a9c7afa95fb3c2c8f0ae576f 100644 (file)
@@ -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;
+}
index 03e4b99f8df451c58764ae903122de020f254e50..779bd15b8c23a469ab6ed2d33380ce2891b2c4eb 100644 (file)
@@ -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 */
index 6065e5f625fdab22eb6d3e4f102440a0611cb356..df7721f267e0a8dcf1c610181c3058180ec9daf6 100644 (file)
@@ -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)
index 3d8beaf169972ab5c5280de30ddf9be45b44c1c7..fe6dfc7d9780929ecc6a0a7770c3ac0dbfa1cacf 100644 (file)
@@ -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)
index 8867ca1e372d0168130e1f90ff785bc93290e36e..9c01cd6a14a51351d562c29f788f4d27de3dad5e 100644 (file)
@@ -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;
 }
index 5aad04f3e17d2f9cab04d4963af5c8f0953c4f58..4a15c34051b4397e67ada681629ef9e999b7f4ab 100644 (file)
@@ -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);
 
index cbb7fd7263f071266dcf14d45c85a920e550daee..f726f0a45d2f938be1b2c02d041e1830936f2dcf 100644 (file)
@@ -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) {