Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af36f906 authored by Tejun Heo's avatar Tejun Heo
Browse files

memcg: always create memsw files if CONFIG_CGROUP_MEM_RES_CTLR_SWAP



Instead of conditioning creation of memsw files on do_swap_account,
always create the files if compiled-in and fail read/write attempts
with -EOPNOTSUPP if !do_swap_account.

This is suggested by KAMEZAWA to simplify memcg file creation so that
it can use cgroup->subsys_cftypes.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
parent 4baf6e33
Loading
Loading
Loading
Loading
+31 −34
Original line number Original line Diff line number Diff line
@@ -3879,14 +3879,21 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
	return val << PAGE_SHIFT;
	return val << PAGE_SHIFT;
}
}


static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft)
static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft,
			       struct file *file, char __user *buf,
			       size_t nbytes, loff_t *ppos)
{
{
	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
	char str[64];
	u64 val;
	u64 val;
	int type, name;
	int type, name, len;


	type = MEMFILE_TYPE(cft->private);
	type = MEMFILE_TYPE(cft->private);
	name = MEMFILE_ATTR(cft->private);
	name = MEMFILE_ATTR(cft->private);

	if (!do_swap_account && type == _MEMSWAP)
		return -EOPNOTSUPP;

	switch (type) {
	switch (type) {
	case _MEM:
	case _MEM:
		if (name == RES_USAGE)
		if (name == RES_USAGE)
@@ -3903,7 +3910,9 @@ static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft)
	default:
	default:
		BUG();
		BUG();
	}
	}
	return val;

	len = scnprintf(str, sizeof(str), "%llu\n", (unsigned long long)val);
	return simple_read_from_buffer(buf, nbytes, ppos, str, len);
}
}
/*
/*
 * The user of this function is...
 * The user of this function is...
@@ -3919,6 +3928,10 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft,


	type = MEMFILE_TYPE(cft->private);
	type = MEMFILE_TYPE(cft->private);
	name = MEMFILE_ATTR(cft->private);
	name = MEMFILE_ATTR(cft->private);

	if (!do_swap_account && type == _MEMSWAP)
		return -EOPNOTSUPP;

	switch (name) {
	switch (name) {
	case RES_LIMIT:
	case RES_LIMIT:
		if (mem_cgroup_is_root(memcg)) { /* Can't set limit on root */
		if (mem_cgroup_is_root(memcg)) { /* Can't set limit on root */
@@ -3984,12 +3997,15 @@ static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,


static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
{
{
	struct mem_cgroup *memcg;
	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
	int type, name;
	int type, name;


	memcg = mem_cgroup_from_cont(cont);
	type = MEMFILE_TYPE(event);
	type = MEMFILE_TYPE(event);
	name = MEMFILE_ATTR(event);
	name = MEMFILE_ATTR(event);

	if (!do_swap_account && type == _MEMSWAP)
		return -EOPNOTSUPP;

	switch (name) {
	switch (name) {
	case RES_MAX_USAGE:
	case RES_MAX_USAGE:
		if (type == _MEM)
		if (type == _MEM)
@@ -4655,7 +4671,7 @@ static struct cftype mem_cgroup_files[] = {
	{
	{
		.name = "usage_in_bytes",
		.name = "usage_in_bytes",
		.private = MEMFILE_PRIVATE(_MEM, RES_USAGE),
		.private = MEMFILE_PRIVATE(_MEM, RES_USAGE),
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
		.register_event = mem_cgroup_usage_register_event,
		.register_event = mem_cgroup_usage_register_event,
		.unregister_event = mem_cgroup_usage_unregister_event,
		.unregister_event = mem_cgroup_usage_unregister_event,
	},
	},
@@ -4663,25 +4679,25 @@ static struct cftype mem_cgroup_files[] = {
		.name = "max_usage_in_bytes",
		.name = "max_usage_in_bytes",
		.private = MEMFILE_PRIVATE(_MEM, RES_MAX_USAGE),
		.private = MEMFILE_PRIVATE(_MEM, RES_MAX_USAGE),
		.trigger = mem_cgroup_reset,
		.trigger = mem_cgroup_reset,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "limit_in_bytes",
		.name = "limit_in_bytes",
		.private = MEMFILE_PRIVATE(_MEM, RES_LIMIT),
		.private = MEMFILE_PRIVATE(_MEM, RES_LIMIT),
		.write_string = mem_cgroup_write,
		.write_string = mem_cgroup_write,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "soft_limit_in_bytes",
		.name = "soft_limit_in_bytes",
		.private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
		.private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
		.write_string = mem_cgroup_write,
		.write_string = mem_cgroup_write,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "failcnt",
		.name = "failcnt",
		.private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT),
		.private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT),
		.trigger = mem_cgroup_reset,
		.trigger = mem_cgroup_reset,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "stat",
		.name = "stat",
@@ -4721,14 +4737,11 @@ static struct cftype mem_cgroup_files[] = {
		.mode = S_IRUGO,
		.mode = S_IRUGO,
	},
	},
#endif
#endif
};

#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
static struct cftype memsw_cgroup_files[] = {
	{
	{
		.name = "memsw.usage_in_bytes",
		.name = "memsw.usage_in_bytes",
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
		.register_event = mem_cgroup_usage_register_event,
		.register_event = mem_cgroup_usage_register_event,
		.unregister_event = mem_cgroup_usage_unregister_event,
		.unregister_event = mem_cgroup_usage_unregister_event,
	},
	},
@@ -4736,35 +4749,22 @@ static struct cftype memsw_cgroup_files[] = {
		.name = "memsw.max_usage_in_bytes",
		.name = "memsw.max_usage_in_bytes",
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
		.trigger = mem_cgroup_reset,
		.trigger = mem_cgroup_reset,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "memsw.limit_in_bytes",
		.name = "memsw.limit_in_bytes",
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
		.write_string = mem_cgroup_write,
		.write_string = mem_cgroup_write,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
	{
	{
		.name = "memsw.failcnt",
		.name = "memsw.failcnt",
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
		.trigger = mem_cgroup_reset,
		.trigger = mem_cgroup_reset,
		.read_u64 = mem_cgroup_read,
		.read = mem_cgroup_read,
	},
	},
};

static int register_memsw_files(struct cgroup *cont, struct cgroup_subsys *ss)
{
	if (!do_swap_account)
		return 0;
	return cgroup_add_files(cont, ss, memsw_cgroup_files,
				ARRAY_SIZE(memsw_cgroup_files));
};
#else
static int register_memsw_files(struct cgroup *cont, struct cgroup_subsys *ss)
{
	return 0;
}
#endif
#endif
};


static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
{
{
@@ -5046,9 +5046,6 @@ static int mem_cgroup_populate(struct cgroup_subsys *ss,
	ret = cgroup_add_files(cont, ss, mem_cgroup_files,
	ret = cgroup_add_files(cont, ss, mem_cgroup_files,
				ARRAY_SIZE(mem_cgroup_files));
				ARRAY_SIZE(mem_cgroup_files));


	if (!ret)
		ret = register_memsw_files(cont, ss);

	if (!ret)
	if (!ret)
		ret = register_kmem_files(cont, ss);
		ret = register_kmem_files(cont, ss);