Commit e147c1c3 authored by zhaoxiaoqiang11's avatar zhaoxiaoqiang11 Committed by Jinjiang Tu
Browse files

memcg/swap: add ability to disable memcg swap

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: default avatarzhaoxiaoqiang11 <zhaoxiaoqiang11@jd.com>
Signed-off-by: default avatarJinjiang Tu <tujinjiang@huawei.com>
parent 2ba9c9b9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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

/*
+20 −6
Original line number Diff line number Diff line
@@ -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;
		}
	}

@@ -8383,7 +8397,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
};