aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2013-02-22 19:34:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:17 -0500
commit2d11085e404f7b45ac4de60db2c9685e349c172d (patch)
treeafc63263964e8b0167113419e2d375e9fd72d4fb /mm/memcontrol.c
parent75f7ad8e043d9383337d917584297f7737154bbf (diff)
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 af36f906c0f4 ("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: Michal Hocko <mhocko@suse.cz> Reported-by: Zhouping Liu <zliu@redhat.com> Tested-by: Zhouping 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c94
1 files changed, 54 insertions, 40 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f85861531f22..00ce03e8a277 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5823,33 +5823,6 @@ static struct cftype mem_cgroup_files[] = {
5823 .read_seq_string = memcg_numa_stat_show, 5823 .read_seq_string = memcg_numa_stat_show,
5824 }, 5824 },
5825#endif 5825#endif
5826#ifdef CONFIG_MEMCG_SWAP
5827 {
5828 .name = "memsw.usage_in_bytes",
5829 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
5830 .read = mem_cgroup_read,
5831 .register_event = mem_cgroup_usage_register_event,
5832 .unregister_event = mem_cgroup_usage_unregister_event,
5833 },
5834 {
5835 .name = "memsw.max_usage_in_bytes",
5836 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
5837 .trigger = mem_cgroup_reset,
5838 .read = mem_cgroup_read,
5839 },
5840 {
5841 .name = "memsw.limit_in_bytes",
5842 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
5843 .write_string = mem_cgroup_write,
5844 .read = mem_cgroup_read,
5845 },
5846 {
5847 .name = "memsw.failcnt",
5848 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
5849 .trigger = mem_cgroup_reset,
5850 .read = mem_cgroup_read,
5851 },
5852#endif
5853#ifdef CONFIG_MEMCG_KMEM 5826#ifdef CONFIG_MEMCG_KMEM
5854 { 5827 {
5855 .name = "kmem.limit_in_bytes", 5828 .name = "kmem.limit_in_bytes",
@@ -5884,6 +5857,36 @@ static struct cftype mem_cgroup_files[] = {
5884 { }, /* terminate */ 5857 { }, /* terminate */
5885}; 5858};
5886 5859
5860#ifdef CONFIG_MEMCG_SWAP
5861static struct cftype memsw_cgroup_files[] = {
5862 {
5863 .name = "memsw.usage_in_bytes",
5864 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
5865 .read = mem_cgroup_read,
5866 .register_event = mem_cgroup_usage_register_event,
5867 .unregister_event = mem_cgroup_usage_unregister_event,
5868 },
5869 {
5870 .name = "memsw.max_usage_in_bytes",
5871 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE),
5872 .trigger = mem_cgroup_reset,
5873 .read = mem_cgroup_read,
5874 },
5875 {
5876 .name = "memsw.limit_in_bytes",
5877 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
5878 .write_string = mem_cgroup_write,
5879 .read = mem_cgroup_read,
5880 },
5881 {
5882 .name = "memsw.failcnt",
5883 .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT),
5884 .trigger = mem_cgroup_reset,
5885 .read = mem_cgroup_read,
5886 },
5887 { }, /* terminate */
5888};
5889#endif
5887static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) 5890static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
5888{ 5891{
5889 struct mem_cgroup_per_node *pn; 5892 struct mem_cgroup_per_node *pn;
@@ -6783,19 +6786,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
6783 .use_id = 1, 6786 .use_id = 1,
6784}; 6787};
6785 6788
6786/*
6787 * The rest of init is performed during ->css_alloc() for root css which
6788 * happens before initcalls. hotcpu_notifier() can't be done together as
6789 * it would introduce circular locking by adding cgroup_lock -> cpu hotplug
6790 * dependency. Do it from a subsys_initcall().
6791 */
6792static int __init mem_cgroup_init(void)
6793{
6794 hotcpu_notifier(memcg_cpu_hotplug_callback, 0);
6795 return 0;
6796}
6797subsys_initcall(mem_cgroup_init);
6798
6799#ifdef CONFIG_MEMCG_SWAP 6789#ifdef CONFIG_MEMCG_SWAP
6800static int __init enable_swap_account(char *s) 6790static int __init enable_swap_account(char *s)
6801{ 6791{
@@ -6808,4 +6798,28 @@ static int __init enable_swap_account(char *s)
6808} 6798}
6809__setup("swapaccount=", enable_swap_account); 6799__setup("swapaccount=", enable_swap_account);
6810 6800
6801static void __init memsw_file_init(void)
6802{
6803 if (really_do_swap_account)
6804 WARN_ON(cgroup_add_cftypes(&mem_cgroup_subsys,
6805 memsw_cgroup_files));
6806}
6807#else
6808static void __init memsw_file_init(void)
6809{
6810}
6811#endif 6811#endif
6812
6813/*
6814 * The rest of init is performed during ->css_alloc() for root css which
6815 * happens before initcalls. hotcpu_notifier() can't be done together as
6816 * it would introduce circular locking by adding cgroup_lock -> cpu hotplug
6817 * dependency. Do it from a subsys_initcall().
6818 */
6819static int __init mem_cgroup_init(void)
6820{
6821 hotcpu_notifier(memcg_cpu_hotplug_callback, 0);
6822 memsw_file_init();
6823 return 0;
6824}
6825subsys_initcall(mem_cgroup_init);