hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8JVN0
--------------------------------
Export "memory.events" and "memory.events.local" from cgroupv2 to cgroupv1.
There are some differences between v2 and v1:
1)events of MEMCG_OOM_GROUP_KILL is not included in cgroupv1. Because, there is no member of memory.oom.group.
2)events of MEMCG_MAX is represented with "limit_in_bytes" in cgroupv1 instead of memory.max
3)event of oom_kill is include in memory.oom_control. oom_kill only show the local cgroup event. Therfore, when CONFIG_MEMCG_V1_RECLAIM=y, use memory_events_local instead of memory_events.
4)enable memory_events contain sub cgroups' counts in cgroupv1.
Signed-off-by: Lu Jialin lujialin4@huawei.com --- include/linux/memcontrol.h | 3 ++- mm/memcontrol.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e4e24da16d2c..8565d064c454 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -1129,9 +1129,10 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg, cgroup_file_notify(&memcg->swap_events_file); else cgroup_file_notify(&memcg->events_file); - +#ifndef CONFIG_MEMCG_V1_RECLAIM if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) break; +#endif if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS) break; } while ((memcg = parent_mem_cgroup(memcg)) && diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 546c28719950..3594b449d5ea 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4528,8 +4528,19 @@ static int mem_cgroup_oom_control_read(struct seq_file *sf, void *v)
seq_printf(sf, "oom_kill_disable %d\n", READ_ONCE(memcg->oom_kill_disable)); seq_printf(sf, "under_oom %d\n", (bool)memcg->under_oom); +/* + * When CONFIG_MEMCG_V1_RECLAIM=n, memory_events[MEMCG_OOM_KILL] equals + * memory_events_local[MEMCG_OOM_KILL]. When CONFIG_MEMCG_V1_RECLAIM=y,memory_events + * will contain sub cgroup counts. Therefore, oom_kill will show + * memory_events_local[MEMCG_OOM_KILL] + */ seq_printf(sf, "oom_kill %lu\n", +#ifdef CONFIG_MEMCG_V1_RECLAIM + atomic_long_read(&memcg->memory_events_local[MEMCG_OOM_KILL])); +#else atomic_long_read(&memcg->memory_events[MEMCG_OOM_KILL])); +#endif + return 0; }
@@ -5022,6 +5033,30 @@ static ssize_t memory_low_write(struct kernfs_open_file *of, static int memory_high_show(struct seq_file *m, void *v); static ssize_t memory_high_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off); +static void __memcg_events_show(struct seq_file *m, atomic_long_t *events) +{ + seq_printf(m, "low %lu\n", atomic_long_read(&events[MEMCG_LOW])); + seq_printf(m, "high %lu\n", atomic_long_read(&events[MEMCG_HIGH])); + seq_printf(m, "limit_in_bytes %lu\n", + atomic_long_read(&events[MEMCG_MAX])); + seq_printf(m, "oom %lu\n", atomic_long_read(&events[MEMCG_OOM])); +} + +static int memcg_events_show(struct seq_file *m, void *v) +{ + struct mem_cgroup *memcg = mem_cgroup_from_seq(m); + + __memcg_events_show(m, memcg->memory_events); + return 0; +} + +static int memcg_events_local_show(struct seq_file *m, void *v) +{ + struct mem_cgroup *memcg = mem_cgroup_from_seq(m); + + __memcg_events_show(m, memcg->memory_events_local); + return 0; +} #endif
static struct cftype mem_cgroup_legacy_files[] = { @@ -5169,6 +5204,18 @@ static struct cftype mem_cgroup_legacy_files[] = { .seq_show = memory_high_show, .write = memory_high_write, }, + { + .name = "events", + .flags = CFTYPE_NOT_ON_ROOT, + .file_offset = offsetof(struct mem_cgroup, events_file), + .seq_show = memcg_events_show, + }, + { + .name = "events.local", + .flags = CFTYPE_NOT_ON_ROOT, + .file_offset = offsetof(struct mem_cgroup, events_local_file), + .seq_show = memcg_events_local_show, + }, #endif { }, /* terminate */ };