From: zhaoxiaoqiang11 zhaoxiaoqiang11@jd.com
jingdong inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8QK6Q CVE: NA
--------------------------------
in cloud native environment, we need to disable container swap and enable it only in special cases.
Usage: echo 2 > /proc/sys/vm/memcg_swap_qos_enable to enable this new feature.
Note: some write operation will be invalid
Valid change: 0 => 1 (enable swap qos, SWAP_TYPE_ALL) 0 => 2 (enable swap qos, SWAP_TYPE_NONE) 1 => 0 (disable swap qos) 2 => 0 (disable swap qos)
Invalid change: 1 => 2 (SWAP_TYPE_ALL => SWAP_TYPE_NONE) 2 => 1 (SWAP_TYPE_NONE => SWAP_TYPE_ALL) and write operation will return -EINVAL
Signed-off-by: zhaoxiaoqiang11 zhaoxiaoqiang11@jd.com Signed-off-by: Jinjiang Tu tujinjiang@huawei.com --- include/linux/memcontrol.h | 5 +++++ mm/memcontrol.c | 26 ++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 3c28d6580258..287d130ee969 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -383,6 +383,11 @@ static inline void memcg_print_bad_task(struct oom_control *oc)
#ifdef CONFIG_MEMCG_SWAP_QOS DECLARE_STATIC_KEY_FALSE(memcg_swap_qos_key); + +#define MEMCG_SWAP_STAT_DISABLE 0 +#define MEMCG_SWAP_STAT_ALL 1 +#define MEMCG_SWAP_STAT_NONE 2 +#define MAX_MEMCG_SWAP_TYPE MEMCG_SWAP_STAT_NONE #endif
/* diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e4ae23325efc..5f2d37bc7c45 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4246,14 +4246,15 @@ DEFINE_STATIC_KEY_FALSE(memcg_swap_qos_key);
#ifdef CONFIG_SYSCTL static int sysctl_memcg_swap_qos_stat; +static int swap_qos_type_max = MAX_MEMCG_SWAP_TYPE;
-static void memcg_swap_qos_reset(void) +static void memcg_swap_qos_reset(int type) { struct mem_cgroup *memcg;
for_each_mem_cgroup(memcg) { WRITE_ONCE(memcg->swap_dev->max, PAGE_COUNTER_MAX); - WRITE_ONCE(memcg->swap_dev->type, SWAP_TYPE_ALL); + WRITE_ONCE(memcg->swap_dev->type, type); } }
@@ -4262,6 +4263,7 @@ static int sysctl_memcg_swap_qos_handler(struct ctl_table *table, int write, { int ret; int qos_stat_old = sysctl_memcg_swap_qos_stat; + int swap_type;
ret = proc_dointvec_minmax(table, write, buffer, length, ppos); if (ret) @@ -4271,12 +4273,24 @@ static int sysctl_memcg_swap_qos_handler(struct ctl_table *table, int write, if (qos_stat_old == sysctl_memcg_swap_qos_stat) return 0;
- if (sysctl_memcg_swap_qos_stat) { - memcg_swap_qos_reset(); + switch (sysctl_memcg_swap_qos_stat) { + case MEMCG_SWAP_STAT_DISABLE: + static_branch_disable(&memcg_swap_qos_key); + return 0; + case MEMCG_SWAP_STAT_ALL: + swap_type = SWAP_TYPE_ALL; + break; + case MEMCG_SWAP_STAT_NONE: + swap_type = SWAP_TYPE_NONE; + break; + } + + if (qos_stat_old == MEMCG_SWAP_STAT_DISABLE) { + memcg_swap_qos_reset(swap_type); static_branch_enable(&memcg_swap_qos_key); enable_swap_slots_cache_max(); } else { - static_branch_disable(&memcg_swap_qos_key); + return -EINVAL; } }
@@ -8387,7 +8401,7 @@ static struct ctl_table mem_cgroup_sysctls[] = { .mode = 0644, .proc_handler = sysctl_memcg_swap_qos_handler, .extra1 = SYSCTL_ZERO, - .extra2 = SYSCTL_ONE, + .extra2 = &swap_qos_type_max, }, #endif };