[Devel] [PATCH RHEL7 COMMIT] ub: do not show dead beancounters under /proc/bc

Konstantin Khorenko khorenko at virtuozzo.com
Mon May 25 03:28:36 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.5
------>
commit 0edaafd2a02f07bad38cc6faffa55cdd5d95cebc
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Mon May 25 14:28:36 2015 +0400

    ub: do not show dead beancounters under /proc/bc
    
    A beancounter is considered "dead" if its cgroup is removed, but it is
    still there. Since we are not going to use beancounters to detect memory
    leaks anymore (memory accounting is up to memcg now), let's zap the code
    for showing dead beancounters under /proc/bc.
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/bc/beancounter.h |  9 +--------
 include/linux/cgroup.h   |  1 -
 kernel/bc/beancounter.c  | 33 ++++++++++++++++++------------
 kernel/bc/proc.c         | 52 +++---------------------------------------------
 kernel/cgroup.c          | 18 -----------------
 5 files changed, 24 insertions(+), 89 deletions(-)

diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h
index a706843..732221b 100644
--- a/include/bc/beancounter.h
+++ b/include/bc/beancounter.h
@@ -115,8 +115,6 @@ struct user_beancounter {
 	unsigned long		ub_magic;
 	struct list_head	ub_list;
 
-	struct rcu_head		rcu;
-
 	spinlock_t		ub_lock;
 	const char		*ub_name;
 
@@ -356,12 +354,7 @@ struct user_beancounter *get_beancounter(struct user_beancounter *ub)
 static inline 
 struct user_beancounter *get_beancounter_rcu(struct user_beancounter *ub)
 {
-	return css_refcnt_inc_not_zero(&ub->css) ? ub : NULL;
-}
-
-static inline bool ub_dead(struct user_beancounter *ub)
-{
-	return !(ub->css.flags & CSS_ONLINE);
+	return css_tryget(&ub->css) ? ub : NULL;
 }
 
 extern uid_t ub_legacy_id(struct user_beancounter *ub);
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index a7b6941..0108a98 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -167,7 +167,6 @@ static inline void css_put(struct cgroup_subsys_state *css)
 }
 
 extern int css_refcnt(struct cgroup_subsys_state *css);
-extern bool css_refcnt_inc_not_zero(struct cgroup_subsys_state *css);
 
 /* bits in struct cgroup flags field */
 enum {
diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
index 4763f7b..546d16f 100644
--- a/kernel/bc/beancounter.c
+++ b/kernel/bc/beancounter.c
@@ -444,14 +444,6 @@ static inline int bc_verify_held(struct user_beancounter *ub)
 	return clean;
 }
 
-static void bc_free_rcu(struct rcu_head *rcu)
-{
-	struct user_beancounter *ub;
-
-	ub = container_of(rcu, struct user_beancounter, rcu);
-	free_ub(ub);
-}
-
 static struct cgroup_subsys_state *ub_cgroup_css_alloc(struct cgroup *cg)
 {
 	struct user_beancounter *ub;
@@ -467,16 +459,25 @@ static struct cgroup_subsys_state *ub_cgroup_css_alloc(struct cgroup *cg)
 	if (!ub)
 		return ERR_PTR(-ENOMEM);
 
+	return &ub->css;
+}
+
+static int ub_cgroup_css_online(struct cgroup *cg)
+{
+	struct user_beancounter *ub = cgroup_ub(cg);
+
+	if (!cg->parent)
+		return 0;
+
 	init_beancounter_nolimits(ub);
 	spin_lock(&ub_list_lock);
 	list_add_rcu(&ub->ub_list, &ub_list_head);
 	ub_count++;
 	spin_unlock(&ub_list_lock);
-
-	return &ub->css;
+	return 0;
 }
 
-static void ub_cgroup_css_free(struct cgroup *cg)
+static void ub_cgroup_css_offline(struct cgroup *cg)
 {
 	struct user_beancounter *ub = cgroup_ub(cg);
 
@@ -484,6 +485,11 @@ static void ub_cgroup_css_free(struct cgroup *cg)
 	ub_count--;
 	list_del_rcu(&ub->ub_list);
 	spin_unlock(&ub_list_lock);
+}
+
+static void ub_cgroup_css_free(struct cgroup *cg)
+{
+	struct user_beancounter *ub = cgroup_ub(cg);
 
 	if (!bc_verify_held(ub)) {
 		printk(KERN_ERR "UB: leaked beancounter %s (%p)\n",
@@ -491,8 +497,7 @@ static void ub_cgroup_css_free(struct cgroup *cg)
 		add_taint(TAINT_CRAP, LOCKDEP_STILL_OK);
 		return;
 	}
-
-	call_rcu(&ub->rcu, bc_free_rcu);
+	free_ub(ub);
 }
 
 static void ub_cgroup_attach_work_fn(struct callback_head *ch)
@@ -675,6 +680,8 @@ struct cgroup_subsys ub_subsys = {
 	.name = "beancounter",
 	.subsys_id = ub_subsys_id,
 	.css_alloc = ub_cgroup_css_alloc,
+	.css_online = ub_cgroup_css_online,
+	.css_offline = ub_cgroup_css_offline,
 	.css_free = ub_cgroup_css_free,
 	.attach = ub_cgroup_attach,
 	.use_id = true,
diff --git a/kernel/bc/proc.c b/kernel/bc/proc.c
index 02b5cfb..a35d3f9 100644
--- a/kernel/bc/proc.c
+++ b/kernel/bc/proc.c
@@ -301,8 +301,6 @@ static int res_show(struct seq_file *f, void *v)
 static int ub_accessible(struct user_beancounter *exec,
 		struct user_beancounter *target)
 {
-	if (ub_dead(target))
-		return 0;
 	return (exec == get_ub0() || exec == target);
 }
 
@@ -496,7 +494,6 @@ static int bc_readdir(struct file *file, filldir_t filler, void *data,
 	loff_t pos, filled;
 	struct user_beancounter *ub, *prev;
 	struct bc_proc_entry *pde;
-	char *buf = NULL;
 
 	if (!(capable(CAP_DAC_OVERRIDE) && capable(CAP_DAC_READ_SEARCH)))
 		return -EPERM;
@@ -540,19 +537,10 @@ static int bc_readdir(struct file *file, filldir_t filler, void *data,
 	if (parent)
 		goto out;
 
-	buf = kmalloc(NAME_MAX + 1, GFP_KERNEL);
-	if (!buf) {
-		err = -ENOMEM;
-		goto out;
-	}
-
 	rcu_read_lock();
 	prev = NULL;
 	ub = list_entry(&ub_list_head, struct user_beancounter, ub_list);
 	while (1) {
-		unsigned long ino;
-		const char *name;
-
 		ub = list_entry(rcu_dereference(ub->ub_list.next),
 				struct user_beancounter, ub_list);
 		if (&ub->ub_list == &ub_list_head)
@@ -569,15 +557,8 @@ static int bc_readdir(struct file *file, filldir_t filler, void *data,
 		rcu_read_unlock();
 		put_beancounter(prev);
 
-		ino = bc_make_ino(ub);
-		name = ub->ub_name;
-		if (ub_dead(ub)) {
-			snprintf(buf, NAME_MAX + 1, "%s-%p", name, ub);
-			name = buf;
-		}
-
-		err = (*filler)(data, name, strlen(name),
-				pos, ino, DT_DIR);
+		err = (*filler)(data, ub->ub_name, strlen(ub->ub_name),
+				pos, bc_make_ino(ub), DT_DIR);
 		if (err < 0) {
 			err = 0;
 			put_beancounter(ub);
@@ -592,7 +573,6 @@ static int bc_readdir(struct file *file, filldir_t filler, void *data,
 	put_beancounter(prev);
 out:
 	file->f_pos = pos;
-	kfree(buf);
 	return err;
 }
 
@@ -803,32 +783,6 @@ static int bc_root_readdir(struct file *file, void *data, filldir_t filler)
 	return bc_readdir(file, filler, data, NULL);
 }
 
-static struct user_beancounter *lookup_beancounter(const char *name)
-{
-	char *p;
-	unsigned long ptr;
-	struct user_beancounter *ub, *ret = NULL;
-
-	p = strrchr(name, '-');
-	if (p && p != name && kstrtoul(p + 1, 16, &ptr) == 0) {
-		rcu_read_lock();
-		for_each_beancounter(ub) {
-			if ((unsigned long)ub != ptr || !ub_dead(ub) ||
-			    strncmp(name, ub->ub_name, max_t(size_t,
-					strlen(ub->ub_name), p - name)))
-				continue;
-			if (get_beancounter_rcu(ub)) {
-				ret = ub;
-				break;
-			}
-		}
-		rcu_read_unlock();
-	}
-	if (!ret)
-		ret = get_beancounter_by_name(name, 0);
-	return ret;
-}
-
 static struct dentry *bc_root_lookup(struct inode *dir, struct dentry *dentry,
 		unsigned int flags)
 {
@@ -842,7 +796,7 @@ static struct dentry *bc_root_lookup(struct inode *dir, struct dentry *dentry,
 	if (de != ERR_PTR(-ESRCH))
 		return de;
 
-	ub = lookup_beancounter(dentry->d_name.name);
+	ub = get_beancounter_by_name(dentry->d_name.name, 0);
 	if (IS_ERR_OR_NULL(ub))
 		return ub ? ERR_CAST(ub) : ERR_PTR(-ENOENT);
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 52c7502..47013a0 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5043,24 +5043,6 @@ static void check_for_release(struct cgroup *cgrp)
 	}
 }
 
-bool css_refcnt_inc_not_zero(struct cgroup_subsys_state *css)
-{
-	if (css->flags & CSS_ROOT)
-		return true;
-
-	while (true) {
-		int t, v;
-
-		v = atomic_read(&css->refcnt);
-		if (!css_unbias_refcnt(v))
-			return false;
-		t = atomic_cmpxchg(&css->refcnt, v, v + 1);
-		if (likely(t == v))
-			return true;
-		cpu_relax();
-	}
-}
-
 /* Caller must verify that the css is not for root cgroup */
 bool __css_tryget(struct cgroup_subsys_state *css)
 {



More information about the Devel mailing list