**/
static struct cgroup cgroup_tree[MEMCG_END] = {
{"/", MEMCG_TOP, CGROUP_DEFAULT_USE_HIERARCHY, NULL},
+ {MEMCG_BACKGROUND_MRU_NAME, MEMCG_ROOT, CGROUP_DEFAULT_USE_HIERARCHY, NULL},
{MEMCG_BACKGROUND_LRU_NAME, MEMCG_ROOT, CGROUP_DEFAULT_USE_HIERARCHY, NULL},
};
static struct memcg_info gmemcg_info[MEMCG_END] = {
{MEMCG_PATH,},
+ {MEMCG_BACKGROUND_MRU_PATH,},
{MEMCG_BACKGROUND_LRU_PATH,},
};
int cgroup_get_type(int oom_score_adj)
{
- if (oom_score_adj >= OOMADJ_BACKGRD_UNLOCKED + OOMADJ_APP_INCREASE &&
+ if (oom_score_adj >= OOMADJ_BACKGRD_PERCEPTIBLE &&
+ oom_score_adj < OOMADJ_BACKGRD_UNLOCKED + OOMADJ_APP_INCREASE)
+ return MEMCG_BACKGROUND_MRU;
+ else if (oom_score_adj >= OOMADJ_BACKGRD_UNLOCKED + OOMADJ_APP_INCREASE &&
oom_score_adj <= OOMADJ_APP_MAX)
return MEMCG_BACKGROUND_LRU;
else
int memcg_write_limiter_params(void)
{
unsigned int i;
- unsigned long long lower_group_limit_bytes = 0;
for (i = MEMCG_BACKGROUND_LRU; i > MEMCG_ROOT; i--) {
struct memcg_info *mi = get_memcg_info(i);
-
- if (mi->limit_bytes < lower_group_limit_bytes)
- mi->limit_bytes = lower_group_limit_bytes;
-
- memcg_write_limiter_info(mi);
- lower_group_limit_bytes = mi->limit_bytes;
+ if (mi)
+ memcg_write_limiter_info(mi);
}
return RESOURCED_ERROR_NONE;
}
-int memcg_write_optimizer_params(void)
+int memcg_write_optimizer_params(enum cgroup_type cgroup_type)
{
- unsigned int i;
-
- for (i = MEMCG_BACKGROUND_LRU; i < MEMCG_END; i++) {
- struct memcg_info *mi = get_memcg_info(i);
- memcg_write_optimizer_info(mi);
- }
+ struct memcg_info *mi = get_memcg_info(cgroup_type);
+ memcg_write_optimizer_info(mi);
return RESOURCED_ERROR_NONE;
}
{
int result;
+ result = cgroup_make_subdir(parentdir, MEMCG_MAKE_NAME(BACKGROUND_MRU), NULL);
+ ret_value_msg_if(result < 0, result, "%s/%s init failed\n",
+ parentdir, MEMCG_MAKE_NAME(BACKGROUND_MRU));
result = cgroup_make_subdir(parentdir, MEMCG_MAKE_NAME(BACKGROUND_LRU), NULL);
ret_value_msg_if(result < 0, result, "%s/%s init failed\n",
parentdir, MEMCG_MAKE_NAME(BACKGROUND_LRU));
/* number of memory cgroups */
#define MEMCG_DEFAULT_EVENT_LEVEL "low"
+#define MEMCG_BACKGROUND_MRU_NAME "BackgroundMru"
#define MEMCG_BACKGROUND_LRU_NAME "BackgroundLru"
#define MEMCG_PRIVATE_NAME "Private"
#define MEMCG_NAME "memory"
#define MEMCG_PATH CGROUP_PATH "/" MEMCG_NAME
+#define MEMCG_BACKGROUND_MRU_PATH MEMCG_PATH "/" MEMCG_BACKGROUND_MRU_NAME
#define MEMCG_BACKGROUND_LRU_PATH MEMCG_PATH "/" MEMCG_BACKGROUND_LRU_NAME
#define MEMCG_PRIVATE_PATH MEMCG_PATH "/" MEMCG_PRIVATE_NAME
/*
* [memory cgroup information]
* MEMCG_ROOT : memory cgroup for root dir
+ * MEMCG_BackgroundMru : memory cgroup for most recently used background app
* MEMCG_BackgroundLru : memory cgroup for least recently used background app
*
* [memory cgroup hierarchy]
* (normal mode)
* root
+ * └─BackgroundMru
* └─BackgroundLru
* └─system.slice/user.slice
*/
enum cgroup_type {
MEMCG_TOP = -1,
MEMCG_ROOT,
+ MEMCG_BACKGROUND_MRU,
MEMCG_BACKGROUND_LRU,
MEMCG_END,
};
enum cgroup_memory_stat_id cgroup_memory_stat_string_to_id(const char *str);
int memcg_write_limiter_params(void);
-int memcg_write_optimizer_params(void);
+int memcg_write_optimizer_params(enum cgroup_type cgroup_type);
void memcg_set_threshold(int type, int level, int value);
void memcg_set_leave_threshold(int type, int value);
swap_conf->enable = false;
swap_conf->boot_reclaim_enable = false;
swap_conf->swap_type = SWAP_TYPE_NONE;
- swap_conf->swappiness[MEMCG_BACKGROUND_LRU] = MEMORY_INIT_SWAPPINESS;
+
+ for (int memcg_idx = MEMCG_ROOT; memcg_idx < MEMCG_END; memcg_idx++)
+ swap_conf->swappiness[memcg_idx] = MEMORY_INIT_SWAPPINESS;
}
}
mi = get_memcg_info(next_memcg_idx);
- if (!mi)
+ if (!mi) {
+ _W("oom_score_adj = %d is out of range", next_oom_score_adj);
return;
+ }
if (!pai) {
cgroup_write_pid_fullpath(mi->name, pid);
proc_set_process_memory_state(pai, next_memcg_idx, mi, next_oom_score_adj);
- if (!lowmem_limit_move_cgroup(pai))
- return;
+ switch (next_memcg_idx) {
+ case MEMCG_ROOT:
+ case MEMCG_BACKGROUND_LRU:
+ if (!lowmem_limit_move_cgroup(pai))
+ return;
+
+ break;
+ case MEMCG_BACKGROUND_MRU:
+ break;
+ default:
+ _E("Unknown memory cgroup index");
+ assert(0);
+ }
+
+ cgroup_write_pid_fullpath(mi->name, pid);
+
+ _I("app (%s) main pid (%d) move %s -> %s (oom = %d -> %d)",
+ pai->appid, pid,
+ lowmem_convert_cgroup_type_to_str(cur_memcg_idx),
+ lowmem_convert_cgroup_type_to_str(next_memcg_idx),
+ cur_oom_score_adj, next_oom_score_adj);
if(cur_memcg_idx == next_memcg_idx)
return;
- _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_BACKGROUND_LRU)
lowmem_swap_memory(get_memcg_info(MEMCG_BACKGROUND_LRU)->name);
} else {
/* child pid */
- if (pai->memory.use_mem_limit)
- return;
+ switch (next_memcg_idx) {
+ case MEMCG_ROOT:
+ case MEMCG_BACKGROUND_LRU:
+ if (pai->memory.use_mem_limit)
+ return;
+ break;
+ case MEMCG_BACKGROUND_MRU:
+ break;
+ default:
+ _E("Unknown memory cgroup index");
+ assert(0);
+ }
cgroup_write_pid_fullpath(mi->name, pid);
+ _I("app (%s) child pid (%d) move -> %s (oom = -> %d)",
+ pai->appid, pid,
+ lowmem_convert_cgroup_type_to_str(next_memcg_idx),
+ next_oom_score_adj);
}
}
const char *lowmem_convert_cgroup_type_to_str(int type)
{
static const char *type_table[] =
- {"/", MEMCG_BACKGROUND_LRU_NAME};
- if (type >= MEMCG_ROOT && type <= MEMCG_BACKGROUND_LRU)
+ {"/", MEMCG_BACKGROUND_MRU_NAME, MEMCG_BACKGROUND_LRU_NAME};
+ if (type > MEMCG_TOP && type < MEMCG_END)
return type_table[type];
else
return "Error";
struct reclaim_conf *reclaim_conf = config_get_reclaim_conf();
/* set MemoryGroupLimit section */
- for (int cgroup = MEMCG_BACKGROUND_LRU; cgroup < MEMCG_END; cgroup++) {
+ for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) {
if (memcg_conf->cgroup_limit[cgroup] > 0.0)
memcg_info_set_limit(get_memcg_info(cgroup),
memcg_conf->cgroup_limit[cgroup]/100.0, totalram_bytes);
static void print_mem_configs(void)
{
/* print info of Memory section */
- for (int cgroup = MEMCG_BACKGROUND_LRU; cgroup < MEMCG_END; cgroup++) {
+ for (int cgroup = MEMCG_ROOT; cgroup < MEMCG_END; cgroup++) {
_I("[MEMORY-CGROUP] set memory for cgroup '%s' to %llu bytes",
lowmem_convert_cgroup_type_to_str(cgroup), get_memcg_info(cgroup)->limit_bytes);
}
swap_conf->swappiness[MEMCG_BACKGROUND_LRU] <= 100) {
memcg_info_set_swappiness(get_memcg_info(MEMCG_BACKGROUND_LRU),
swap_conf->swappiness[MEMCG_BACKGROUND_LRU]);
- memcg_write_optimizer_params();
+ memcg_write_optimizer_params(MEMCG_BACKGROUND_LRU);
_I("[SWAP] cgroup (%s) swapiness = %d", MEMCG_BACKGROUND_LRU_NAME,
get_memcg_info(MEMCG_BACKGROUND_LRU)->swappiness);
}