Commit 87a2560d authored by Jinjiang Tu's avatar Jinjiang Tu
Browse files

mm/memcontrol: add ksm state for memcg

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9GT87



----------------------------------------

Add KSM state for memcg, the valid values include 0 and 1.

When changing auto_ksm_enabled from 0 to 1, enable KSM for tasks in the
memcg. When changing auto_ksm_enabled from 1 to 0, disable KSM for tasks
in the memcg. If enable/disable fails, return the error code and don't
change auto_ksm_enabled. If the auto_ksm_state of the child memcgs differ,
also enable/disable KSM for the tasks in the memcgs. If enable/disable
for a child memcg fails, stop traversing child memcgs and return the
error code.

When writing the value same to auto_ksm_enabled of the memcg, i.e. from 0
to 0 and 1 to 1, do nothing.

Signed-off-by: default avatarJinjiang Tu <tujinjiang@huawei.com>
parent c5723c0b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -414,7 +414,11 @@ struct mem_cgroup {
#else
	KABI_RESERVE(7)
#endif
#ifdef CONFIG_KSM
	KABI_USE(8, bool auto_ksm_enabled)
#else
	KABI_RESERVE(8)
#endif

	struct mem_cgroup_per_node *nodeinfo[0];
	/* WARNING: nodeinfo must be the last member here */
+29 −1
Original line number Diff line number Diff line
@@ -5772,7 +5772,7 @@ static ssize_t memcg_high_async_ratio_write(struct kernfs_open_file *of,
}

#ifdef CONFIG_KSM
static int memcg_set_ksm_for_tasks(struct mem_cgroup *memcg, bool enable)
static int __memcg_set_ksm_for_tasks(struct mem_cgroup *memcg, bool enable)
{
	struct task_struct *task;
	struct mm_struct *mm;
@@ -5806,6 +5806,27 @@ static int memcg_set_ksm_for_tasks(struct mem_cgroup *memcg, bool enable)
	return ret;
}

static int memcg_set_ksm_for_tasks(struct mem_cgroup *memcg, bool enable)
{
	struct mem_cgroup *iter;
	int ret = 0;

	for_each_mem_cgroup_tree(iter, memcg) {
		if (READ_ONCE(iter->auto_ksm_enabled) == enable)
			continue;

		ret = __memcg_set_ksm_for_tasks(iter, enable);
		if (ret) {
			mem_cgroup_iter_break(memcg, iter);
			break;
		}

		WRITE_ONCE(iter->auto_ksm_enabled, enable);
	}

	return ret;
}

static int memory_ksm_show(struct seq_file *m, void *v)
{
	unsigned long ksm_merging_pages = 0;
@@ -5833,6 +5854,7 @@ static int memory_ksm_show(struct seq_file *m, void *v)
	}
	css_task_iter_end(&it);

	seq_printf(m, "auto ksm enabled: %d\n", READ_ONCE(memcg->auto_ksm_enabled));
	seq_printf(m, "merge any tasks: %u\n", tasks);
	seq_printf(m, "ksm_rmap_items %lu\n", ksm_rmap_items);
	seq_printf(m, "ksm_merging_pages %lu\n", ksm_merging_pages);
@@ -5855,6 +5877,9 @@ static ssize_t memory_ksm_write(struct kernfs_open_file *of, char *buf,
	if (err)
		return err;

	if (READ_ONCE(memcg->auto_ksm_enabled) == enable)
		return nbytes;

	err = memcg_set_ksm_for_tasks(memcg, enable);
	if (err)
		return err;
@@ -6430,6 +6455,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
	}

	hugetlb_pool_inherit(memcg, parent);
#ifdef CONFIG_KSM
	memcg->auto_ksm_enabled = READ_ONCE(parent->auto_ksm_enabled);
#endif

	error = memcg_online_kmem(memcg);
	if (error)