[Devel] [PATCH rh7] cgroup/debug: disable css_get/put stacks saver by default.

Andrey Ryabinin aryabinin at virtuozzo.com
Fri Mar 13 17:42:41 MSK 2020


Disable css_get/put stacks saver by default as they have too much
overhead. Add file in debugfs to enable it:

	  echo 1 > /sys/kernel/debug/css_stacks

Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 include/linux/cgroup.h | 12 +++++++++--
 kernel/cgroup.c        | 45 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index a2c5f0717072..bd48216e7ac2 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -150,14 +150,22 @@ enum {
 	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
 };
 
+
+extern struct static_key css_stacks_on;
+void __save_css_stack(struct cgroup_subsys_state *css);
+
+static inline void save_css_stack(struct cgroup_subsys_state *css)
+{
+	if (static_key_false(&css_stacks_on))
+		__save_css_stack(css);
+}
+
 /*
  * Call css_get() to hold a reference on the css; it can be used
  * for a reference obtained via:
  * - an existing ref-counted reference to the css
  * - task->cgroups for a locked task
  */
-void save_css_stack(struct cgroup_subsys_state *css);
-
 static inline void css_get(struct cgroup_subsys_state *css)
 {
 	/* We don't need to reference count the root state */
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index f46ef8de43ee..50d4b3df0f0a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -29,6 +29,7 @@
 #include <linux/cgroup.h>
 #include <linux/cred.h>
 #include <linux/ctype.h>
+#include <linux/debugfs.h>
 #include <linux/errno.h>
 #include <linux/init_task.h>
 #include <linux/kernel.h>
@@ -4165,13 +4166,51 @@ static void css_release(struct percpu_ref *ref)
 	queue_work(cgroup_destroy_wq, &css->dput_work);
 }
 
+struct static_key css_stacks_on = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL(css_stacks_on);
+
+#ifdef CONFIG_DEBUG_FS
+static int css_stacks_get(void *data, u64 *val)
+{
+	*val = static_key_false(&css_stacks_on);
+	return 0;
+}
+
+static int css_stacks_set(void *data, u64 val)
+{
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	if (static_key_false(&css_stacks_on) && !val)
+		static_key_slow_dec(&css_stacks_on);
+	else if (!static_key_false(&css_stacks_on) && val)
+		static_key_slow_inc(&css_stacks_on);
+
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(css_stacks_fops,
+		css_stacks_get, css_stacks_set, "%llu\n");
+
+static int __init css_stacks_debugfs(void)
+{
+	void *ret;
+
+	ret = debugfs_create_file("css_stacks",	0644, NULL, NULL,
+			&css_stacks_fops);
+	if (!ret)
+		pr_warn("Failed to create css_stacks in debugfs");
+	return 0;
+}
+late_initcall(css_stacks_debugfs);
+#endif
+
 static void init_cgroup_css(struct cgroup_subsys_state *css,
 			       struct cgroup_subsys *ss,
 			       struct cgroup *cgrp)
 {
 	css->cgroup = cgrp;
 	css->flags = 0;
-	if (slab_is_available())
+	if (static_key_false(&css_stacks_on) && slab_is_available())
 		css->stacks = (struct css_stacks *)
 			__get_free_pages(GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO, 1);
 	else
@@ -4204,7 +4243,7 @@ static int online_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
 	return ret;
 }
 
-void save_css_stack(struct cgroup_subsys_state *css)
+void __save_css_stack(struct cgroup_subsys_state *css)
 {
 	unsigned long entries[8];
 	unsigned int offset;
@@ -4229,7 +4268,7 @@ void save_css_stack(struct cgroup_subsys_state *css)
 	save_stack_trace(&trace);
 	memcpy(((char*)css_stacks)+offset, entries, trace.max_entries*8);
 }
-EXPORT_SYMBOL(save_css_stack);
+EXPORT_SYMBOL(__save_css_stack);
 
 /* if the CSS is online, invoke ->pre_destory() on it and mark it offline */
 static void offline_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
-- 
2.24.1



More information about the Devel mailing list