[Devel] [PATCH RHEL9 COMMIT] mm/oom_kill: count global OOM
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jan 27 20:08:51 MSK 2022
The commit is pushed to "branch-rh9-5.14.0-4.vz9.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-4.vz9.12.2
------>
commit 76d51fcb04a2dc91c2d6a96e8a11e291494dacb7
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date: Thu Jan 27 20:08:51 2022 +0300
mm/oom_kill: count global OOM
Currently we try to calculate global OOM count by substructing cgroup OOMs
from OOM_KILLs. However there are two problems with that:
- OOM *may* not lead to OOM_KILL
- berserker can make several OOM_KILL per one OOM
Introduce new variable and start accounting global OOM to it so we can
later print statistics.
khorenko@:
memcg->memory_events[MEMCG_OOM] - non-hierarchical counter of OOMs
happened in this cgroup
memcg->memory_events[MEMCG_OOM_KILL] - non-hierarchical counter for number of
process kills happened in this memory
cgroup. The kill could happened due to
OOM happened in this memcg or in
parent/grandparent/etc memcg
global_oom (newly introduced) - counter for global OOM cases
Seems memcg->memory_events[MEMCG_OOM] for root memcg should be always zero
because root memcg cannot be configured and thus cannot cause OOM. But in
memcg_stat_show() we keep summing this counter - just in case.
https://jira.sw.ru/browse/PSBM-131983
Fixes: 151f5149f1c2 ("mm, memcg: add oom counter to memory.stat memcgroup file")
Feature: mm: statistic enhancements
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
mm/memcontrol.c | 9 +++++----
mm/oom_kill.c | 5 +++++
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 8b7dee74004b..80670173b385 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4613,6 +4613,8 @@ static void accumulate_ooms(struct mem_cgroup *memcg, unsigned long *oom,
*kill = total_oom_kill;
}
+extern atomic_t global_oom;
+
static int memcg_stat_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_seq(m);
@@ -4645,11 +4647,10 @@ static int memcg_stat_show(struct seq_file *m, void *v)
/*
* For root_mem_cgroup we want to account global ooms as well.
- * The diff between all 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", total_oom_kill - total_oom);
+ seq_printf(m, "oom %lu\n", atomic_read(&global_oom) +
+ atomic_long_read(&memcg->memory_events[MEMCG_OOM]));
else
seq_printf(m, "oom %lu\n",
atomic_long_read(&memcg->memory_events[MEMCG_OOM]));
@@ -4689,7 +4690,7 @@ static int memcg_stat_show(struct seq_file *m, void *v)
(u64)memcg_events(memcg, memcg1_events[i]));
if (memcg == root_mem_cgroup)
- seq_printf(m, "total_oom %lu\n", total_oom_kill);
+ seq_printf(m, "total_oom %lu\n", total_oom + atomic_read(&global_oom));
else
seq_printf(m, "total_oom %lu\n", total_oom);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 47c8f292a0e8..98fea6dcb018 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -1075,6 +1075,8 @@ static void oom_berserker(struct oom_control *oc)
pr_err("OOM killer in rage %d: %d tasks killed\n", rage, killed);
}
+atomic_t global_oom = ATOMIC_INIT(0);
+
static void oom_kill_process(struct oom_control *oc, const char *message)
{
struct task_struct *victim = oc->chosen;
@@ -1098,6 +1100,9 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
}
task_unlock(victim);
+ if (!is_memcg_oom(oc))
+ atomic_inc(&global_oom);
+
if (__ratelimit(&oom_rs))
dump_header(oc, victim);
More information about the Devel
mailing list