hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8JVN0
-------------------------------
Introduce CONFIG_MEMCG_V1_THRESHOLD_QOS to isolate memcg qos management feature from baseline.
Signed-off-by: Lu Jialin lujialin4@huawei.com --- arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + include/linux/memcontrol.h | 10 +++++++++- init/Kconfig | 6 ++++++ mm/memcontrol.c | 16 ++++++++++++++-- 5 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 8f1a4db8d49b..40f9c1ad1c0e 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -157,6 +157,7 @@ CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y # CONFIG_CGROUP_FAVOR_DYNMODS is not set CONFIG_MEMCG=y +CONFIG_MEMCG_V1_THRESHOLD_QOS=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 507d199ff598..6b806dd5b3cb 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -179,6 +179,7 @@ CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y # CONFIG_CGROUP_FAVOR_DYNMODS is not set CONFIG_MEMCG=y +CONFIG_MEMCG_V1_THRESHOLD_QOS=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 8e1ae2d252c6..294ca0f5b55a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -332,8 +332,11 @@ struct mem_cgroup { /* per-memcg mm_struct list */ struct lru_gen_mm_list mm_list; #endif + +#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS int high_async_ratio; bool high_async_reclaim; +#endif
struct mem_cgroup_per_node *nodeinfo[]; }; @@ -1121,8 +1124,10 @@ static bool memcg_event_add(struct mem_cgroup *memcg, if (!mem_cgroup_is_root(memcg)) return true;
+#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS if (event == MEMCG_OOM_KILL && !cgroup_subsys_on_dfl(memory_cgrp_subsys)) return true; +#endif
return false; } @@ -1143,7 +1148,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_THRESHOLD_QOS + 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/init/Kconfig b/init/Kconfig index 6d35728b94b2..f80fffbd565c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -944,6 +944,12 @@ config MEMCG help Provides control over the memory footprint of tasks in a cgroup.
+config MEMCG_V1_THRESHOLD_QOS + bool "Qos memcg threshold in v1" + depends on MEMCG + default n + + config MEMCG_KMEM bool depends on MEMCG diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 5a808d88e27a..278a14c09f94 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2418,6 +2418,7 @@ static unsigned long reclaim_high(struct mem_cgroup *memcg, return nr_reclaimed; }
+#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS static bool is_high_async_reclaim(struct mem_cgroup *memcg) { int ratio = READ_ONCE(memcg->high_async_ratio); @@ -2450,15 +2451,18 @@ static void async_reclaim_high(struct mem_cgroup *memcg) psi_memstall_leave(&pflags); WRITE_ONCE(memcg->high_async_reclaim, false); } +#endif
static void high_work_func(struct work_struct *work) { struct mem_cgroup *memcg = container_of(work, struct mem_cgroup, high_work);
+#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS if (READ_ONCE(memcg->high_async_reclaim)) async_reclaim_high(memcg); else +#endif reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL); }
@@ -2847,12 +2851,13 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask, } continue; } - +#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS if (is_high_async_reclaim(memcg) && !mem_high) { WRITE_ONCE(memcg->high_async_reclaim, true); schedule_work(&memcg->high_work); break; } +#endif
if (mem_high || swap_high) { /* @@ -4583,8 +4588,10 @@ static int mem_cgroup_oom_control_read(struct seq_file *sf, void *v) seq_printf(sf, "under_oom %d\n", (bool)memcg->under_oom); seq_printf(sf, "oom_kill %lu\n", atomic_long_read(&memcg->memory_events[MEMCG_OOM_KILL])); +#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS seq_printf(sf, "oom_kill_local %lu\n", atomic_long_read(&memcg->memory_events_local[MEMCG_OOM_KILL])); +#endif
return 0; } @@ -5171,6 +5178,7 @@ static ssize_t memory_high_write(struct kernfs_open_file *of, return nbytes; }
+#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS 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])); @@ -5195,7 +5203,6 @@ static int memcg_events_local_show(struct seq_file *m, void *v) __memcg_events_show(m, memcg->memory_events_local); return 0; } - static int memcg_high_async_ratio_show(struct seq_file *m, void *v) { seq_printf(m, "%d\n", @@ -5225,6 +5232,7 @@ static ssize_t memcg_high_async_ratio_write(struct kernfs_open_file *of,
return nbytes; } +#endif
static int memory_stat_show(struct seq_file *m, void *v);
@@ -5354,6 +5362,7 @@ static struct cftype mem_cgroup_legacy_files[] = { .write = mem_cgroup_reset, .read_u64 = mem_cgroup_read_u64, }, +#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS { .name = "min", .flags = CFTYPE_NOT_ON_ROOT, @@ -5390,6 +5399,7 @@ static struct cftype mem_cgroup_legacy_files[] = { .seq_show = memcg_high_async_ratio_show, .write = memcg_high_async_ratio_write, }, +#endif
{ }, /* terminate */ }; @@ -5618,7 +5628,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_ZSWAP) memcg->zswap_max = PAGE_COUNTER_MAX; #endif +#ifdef CONFIG_MEMCG_V1_THRESHOLD_QOS memcg->high_async_ratio = HIGH_ASYNC_RATIO_BASE; +#endif page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX); if (parent) { WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));