[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