[Devel] [PATCH RH9] mm/oom_kill: count global OOM

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Wed Jan 26 16:02:02 MSK 2022


Currently we try to calculate global OOM count by substructing cgroup OOMs
from OOM_KILLs. However there is 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.

https://jira.sw.ru/browse/PSBM-131983
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);
 
-- 
2.35.0.rc2



More information about the Devel mailing list