From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 10 Dec 2015 18:02:48 +0000
Subject: cgroups: Allow memory cgroup support to be included but disabled
Forwarded: no

Memory cgroup support has some run-time overhead, so it's useful to
include it in a distribution kernel without enabling it by default.
Add a kernel config option to disable it by default and a kernel
parameter 'cgroup_enable' as the opposite to 'cgroup_disable'.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
[Bastian Blank: Rename CGROUP_MEM_RES_CTLR_DISABLED to MEMCG_DISABLED]
---
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -597,8 +597,8 @@ bytes respectively. Such letter suffixes
 	ccw_timeout_log [S390]
 			See Documentation/s390/CommonIO for details.
 
-	cgroup_disable= [KNL] Disable a particular controller
-			Format: {name of the controller(s) to disable}
+	cgroup_disable= [KNL] Disable/enable a particular controller
+	cgroup_enable=	Format: {name of the controller(s) to disable/enable}
 			The effects of cgroup_disable=foo are:
 			- foo isn't auto-mounted if you mount all cgroups in
 			  a single hierarchy
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -945,6 +945,14 @@ config MEMCG
 	help
 	  Provides control over the memory footprint of tasks in a cgroup.
 
+config MEMCG_DISABLED
+	bool "Memory Resource Controller disabled by default"
+	depends on MEMCG
+	default n
+	help
+	  Disable the memory group resource controller unless explicitly
+	  enabled using the kernel parameter "cgroup_enable=memory".
+
 config MEMCG_SWAP
 	bool "Swap controller"
 	depends on MEMCG && SWAP
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5269,7 +5269,11 @@ int __init cgroup_init_early(void)
 	return 0;
 }
 
+#ifdef CONFIG_MEMCG_DISABLED
+static unsigned long cgroup_disable_mask __initdata = 1 << memory_cgrp_id;
+#else
 static unsigned long cgroup_disable_mask __initdata;
+#endif
 
 /**
  * cgroup_init - cgroup initialization
@@ -5729,7 +5733,7 @@ out_free:
 	kfree(pathbuf);
 }
 
-static int __init cgroup_disable(char *str)
+static int __init cgroup_set_disabled(char *str, int value)
 {
 	struct cgroup_subsys *ss;
 	char *token;
@@ -5743,13 +5747,27 @@ static int __init cgroup_disable(char *s
 			if (strcmp(token, ss->name) &&
 			    strcmp(token, ss->legacy_name))
 				continue;
-			cgroup_disable_mask |= 1 << i;
+			if (value)
+				cgroup_disable_mask |= 1 << i;
+			else
+				cgroup_disable_mask &= ~(1 << i);
 		}
 	}
 	return 1;
 }
+
+static int __init cgroup_disable(char *str)
+{
+	return cgroup_set_disabled(str, 1);
+}
 __setup("cgroup_disable=", cgroup_disable);
 
+static int __init cgroup_enable(char *str)
+{
+	return cgroup_set_disabled(str, 0);
+}
+__setup("cgroup_enable=", cgroup_enable);
+
 /**
  * css_tryget_online_from_dir - get corresponding css from a cgroup dentry
  * @dentry: directory dentry of interest
