Add oom counter to memory.stat file. oom shows amount of oom kills triggered due to cgroup's memory limit. total_oom shows total sum of oom kills triggered due to cgroup's and it's sub-groups memory limits.
memory.stat in the root cgroup counts global oom kills. E.g: # mkdir /sys/fs/cgroup/memory/test/ # echo 100M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes # echo 100M > /sys/fs/cgroup/memory/test/memory.memsw.limit_in_bytes # echo $$ > /sys/fs/cgroup/memory/test/tasks # ./vm-scalability/usemem -O 200M # grep oom /sys/fs/cgroup/memory/test/memory.stat oom 1 total_oom 1 # echo -1 > /sys/fs/cgroup/memory/test/memory.memsw.limit_in_bytes # echo -1 > /sys/fs/cgroup/memory/test/memory.limit_in_bytes # ./vm-scalability/usemem -O 1000G # grep oom /sys/fs/cgroup/memory/memory.stat oom 1 total_oom 2 https://jira.sw.ru/browse/PSBM-108287 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> --- include/linux/memcontrol.h | 2 ++ mm/memcontrol.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index b097f137a3df..eb8634128a81 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -75,6 +75,8 @@ struct accumulated_stats { unsigned long stat[MEMCG_NR_STAT]; unsigned long events[NR_VM_EVENT_ITEMS]; unsigned long lru_pages[NR_LRU_LISTS]; + unsigned long oom; + unsigned long oom_kill; const unsigned int *stats_array; const unsigned int *events_array; int stats_size; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 37d4df653f39..ca3a07543416 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3144,6 +3144,8 @@ void accumulate_memcg_tree(struct mem_cgroup *memcg, for (i = 0; i < NR_LRU_LISTS; i++) acc->lru_pages[i] += mem_cgroup_nr_lru_pages(mi, BIT(i)); + acc->oom += atomic_long_read(&mi->memory_events[MEMCG_OOM]); + acc->oom_kill += atomic_long_read(&mi->memory_events[MEMCG_OOM_KILL]); cond_resched(); } @@ -3899,6 +3901,13 @@ static int memcg_stat_show(struct seq_file *m, void *v) BUILD_BUG_ON(ARRAY_SIZE(memcg1_stat_names) != ARRAY_SIZE(memcg1_stats)); BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); + memset(&acc, 0, sizeof(acc)); + acc.stats_size = ARRAY_SIZE(memcg1_stats); + acc.stats_array = memcg1_stats; + acc.events_size = ARRAY_SIZE(memcg1_events); + acc.events_array = memcg1_events; + accumulate_memcg_tree(memcg, &acc); + for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) { if (memcg1_stats[i] == MEMCG_SWAP && !do_memsw_account()) continue; @@ -3911,6 +3920,18 @@ static int memcg_stat_show(struct seq_file *m, void *v) seq_printf(m, "%s %lu\n", memcg1_event_names[i], memcg_sum_events(memcg, memcg1_events[i])); + /* + * For root_mem_cgroup we want to account global ooms as well. + * The diff between allo MEMCG_OOM_KILL and MEMCG_OOM events + * should give us the glogbal ooms count. + */ + if (memcg == root_mem_cgroup) + seq_printf(m, "oom %lu\n", acc.oom_kill - acc.oom + + atomic_long_read(&memcg->memory_events[MEMCG_OOM])); + else + seq_printf(m, "oom %lu\n", + atomic_long_read(&memcg->memory_events[MEMCG_OOM])); + for (i = 0; i < NR_LRU_LISTS; i++) seq_printf(m, "%s %lu\n", mem_cgroup_lru_names[i], mem_cgroup_nr_lru_pages(memcg, BIT(i)) * PAGE_SIZE); @@ -3927,13 +3948,6 @@ static int memcg_stat_show(struct seq_file *m, void *v) seq_printf(m, "hierarchical_memsw_limit %llu\n", (u64)memsw * PAGE_SIZE); - memset(&acc, 0, sizeof(acc)); - acc.stats_size = ARRAY_SIZE(memcg1_stats); - acc.stats_array = memcg1_stats; - acc.events_size = ARRAY_SIZE(memcg1_events); - acc.events_array = memcg1_events; - accumulate_memcg_tree(memcg, &acc); - for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) { if (memcg1_stats[i] == MEMCG_SWAP && !do_memsw_account()) continue; @@ -3945,6 +3959,11 @@ static int memcg_stat_show(struct seq_file *m, void *v) seq_printf(m, "total_%s %llu\n", memcg1_event_names[i], (u64)acc.events[i]); + if (memcg == root_mem_cgroup) + seq_printf(m, "total_oom %lu\n", acc.oom_kill); + else + seq_printf(m, "total_oom %lu\n", acc.oom); + for (i = 0; i < NR_LRU_LISTS; i++) seq_printf(m, "total_%s %llu\n", mem_cgroup_lru_names[i], (u64)acc.lru_pages[i] * PAGE_SIZE); -- 2.26.2 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel