提交 2d11085e 编写于 作者: M Michal Hocko 提交者: Linus Torvalds

memcg: do not create memsw files if swap accounting is disabled

Zhouping Liu has reported that memsw files are exported even though swap
accounting is runtime disabled if MEMCG_SWAP is enabled.  This behavior
has been introduced by commit af36f906 ("memcg: always create memsw
files if CGROUP_MEM_RES_CTLR_SWAP") and it causes any attempt to open
the file to return EOPNOTSUPP.  Although EOPNOTSUPP should say be clear
that memsw operations are not supported in the given configuration it is
fair to say that this behavior could be quite confusing.

Let's tear memsw files out of default cgroup files and add them only if
the swap accounting is really enabled (either by MEMCG_SWAP_ENABLED or
swapaccount=1 boot parameter).  We can hook into mem_cgroup_init which
is called when the memcg subsystem is initialized and which happens
after boot command line is processed.
Signed-off-by: NMichal Hocko <mhocko@suse.cz>
Reported-by: NZhouping Liu <zliu@redhat.com>
Tested-by: NZhouping Liu <zliu@redhat.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: CAI Qian <caiqian@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 75f7ad8e
...@@ -5823,33 +5823,6 @@ static struct cftype mem_cgroup_files[] = { ...@@ -5823,33 +5823,6 @@ static struct cftype mem_cgroup_files[] = {
.read_seq_string = memcg_numa_stat_show, .read_seq_string = memcg_numa_stat_show,
}, },
#endif #endif
#ifdef CONFIG_MEMCG_SWAP
{
.name = "memsw.usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
.read = mem_cgroup_read,
.register_event = mem_cgroup_usage_register_event,
.unregister_event = mem_cgroup_usage_unregister_event,
},
{
.name = "memsw.max_usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
.trigger = mem_cgroup_reset,
.read = mem_cgroup_read,
},
{
.name = "memsw.limit_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
.write_string = mem_cgroup_write,
.read = mem_cgroup_read,
},
{
.name = "memsw.failcnt",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
.trigger = mem_cgroup_reset,
.read = mem_cgroup_read,
},
#endif
#ifdef CONFIG_MEMCG_KMEM #ifdef CONFIG_MEMCG_KMEM
{ {
.name = "kmem.limit_in_bytes", .name = "kmem.limit_in_bytes",
...@@ -5884,6 +5857,36 @@ static struct cftype mem_cgroup_files[] = { ...@@ -5884,6 +5857,36 @@ static struct cftype mem_cgroup_files[] = {
{ }, /* terminate */ { }, /* terminate */
}; };
#ifdef CONFIG_MEMCG_SWAP
static struct cftype memsw_cgroup_files[] = {
{
.name = "memsw.usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
.read = mem_cgroup_read,
.register_event = mem_cgroup_usage_register_event,
.unregister_event = mem_cgroup_usage_unregister_event,
},
{
.name = "memsw.max_usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
.trigger = mem_cgroup_reset,
.read = mem_cgroup_read,
},
{
.name = "memsw.limit_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
.write_string = mem_cgroup_write,
.read = mem_cgroup_read,
},
{
.name = "memsw.failcnt",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
.trigger = mem_cgroup_reset,
.read = mem_cgroup_read,
},
{ }, /* terminate */
};
#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)
{ {
struct mem_cgroup_per_node *pn; struct mem_cgroup_per_node *pn;
...@@ -6783,19 +6786,6 @@ struct cgroup_subsys mem_cgroup_subsys = { ...@@ -6783,19 +6786,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
.use_id = 1, .use_id = 1,
}; };
/*
* The rest of init is performed during ->css_alloc() for root css which
* happens before initcalls. hotcpu_notifier() can't be done together as
* it would introduce circular locking by adding cgroup_lock -> cpu hotplug
* dependency. Do it from a subsys_initcall().
*/
static int __init mem_cgroup_init(void)
{
hotcpu_notifier(memcg_cpu_hotplug_callback, 0);
return 0;
}
subsys_initcall(mem_cgroup_init);
#ifdef CONFIG_MEMCG_SWAP #ifdef CONFIG_MEMCG_SWAP
static int __init enable_swap_account(char *s) static int __init enable_swap_account(char *s)
{ {
...@@ -6808,4 +6798,28 @@ static int __init enable_swap_account(char *s) ...@@ -6808,4 +6798,28 @@ static int __init enable_swap_account(char *s)
} }
__setup("swapaccount=", enable_swap_account); __setup("swapaccount=", enable_swap_account);
static void __init memsw_file_init(void)
{
if (really_do_swap_account)
WARN_ON(cgroup_add_cftypes(&mem_cgroup_subsys,
memsw_cgroup_files));
}
#else
static void __init memsw_file_init(void)
{
}
#endif #endif
/*
* The rest of init is performed during ->css_alloc() for root css which
* happens before initcalls. hotcpu_notifier() can't be done together as
* it would introduce circular locking by adding cgroup_lock -> cpu hotplug
* dependency. Do it from a subsys_initcall().
*/
static int __init mem_cgroup_init(void)
{
hotcpu_notifier(memcg_cpu_hotplug_callback, 0);
memsw_file_init();
return 0;
}
subsys_initcall(mem_cgroup_init);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册