All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cgroup: bug fix of cgroup_root object was not released after cgroup umounted
@ 2015-12-14 11:45 ` kyler.zhangkui
  0 siblings, 0 replies; 3+ messages in thread
From: kyler.zhangkui @ 2015-12-14 11:45 UTC (permalink / raw)
  To: cgroups; +Cc: tj, zhihui.gao, chenjie6, lizefan, Zhang Kui, stable

From: Zhang Kui <kyler.zhangkui@huawei.com>

Newsgroups: gmane.linux.kernel.cgroups, gmane.linux.kernel

test case:
    # cat test.sh
    mkdir rootdir
    mount -t cgroup xxx rootdir -o cpu

    mkdir rootdir/0

    rmdir rootdir/0
    umount rootdir

    rmdir rootdir
    # ./test.sh
    # cat /proc/cgroups
    #subsys_name    hierarchy       num_cgroups     enabled
    cpuset  0       1       1
    cpu     1       1       1
    cpuacct 0       1       1
    blkio   0       1       1
    devices 0       1       1
    freezer 0       1       1
    debug   0       1       1

The rootdir's cgroup_root is not released after it is umounted, the cpu
subsystem hierarchy id is not zero.
After that, can not mount other subsystem except cpu on the folder
rootdir.
It is because "rmdir rootdir/0" real action is done in workqueue,
the sub-cgroup "0" has not beend delete from the root->cgrp.self.children
during running "umount rootdir".

Fix this by checking whether cgroup_root has online child on umounting.

Cc: <stable@vger.kernel.org> # 4.1.y+
Signed-off-by: Zhang Kui <kyler.zhangkui@huawei.com>
---
 kernel/cgroup.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index f1603c1..ec6aecc 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2147,6 +2147,13 @@ static void cgroup_kill_sb(struct super_block *sb)
 {
 	struct kernfs_root *kf_root = kernfs_root_from_sb(sb);
 	struct cgroup_root *root = cgroup_root_from_kf(kf_root);
+	struct cgroup *child;
+	int live_child = 0;
+
+	mutex_lock(&cgroup_mutex);
+	cgroup_for_each_live_child(child, &root->cgrp) {
+		live_child++;
+	}
 
 	/*
 	 * If @root doesn't have any mounts or children, start killing it.
@@ -2155,12 +2162,12 @@ static void cgroup_kill_sb(struct super_block *sb)
 	 *
 	 * And don't kill the default root.
 	 */
-	if (!list_empty(&root->cgrp.self.children) ||
-	    root == &cgrp_dfl_root)
-		cgroup_put(&root->cgrp);
+	if (live_child || root == &cgrp_dfl_root)
+	cgroup_put(&root->cgrp);
 	else
 		percpu_ref_kill(&root->cgrp.self.refcnt);
 
+	mutex_unlock(&cgroup_mutex);
 	kernfs_kill_sb(sb);
 }
 
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] cgroup: bug fix of cgroup_root object was not released after cgroup umounted
@ 2015-12-14 11:45 ` kyler.zhangkui
  0 siblings, 0 replies; 3+ messages in thread
From: kyler.zhangkui @ 2015-12-14 11:45 UTC (permalink / raw)
  To: cgroups; +Cc: tj, zhihui.gao, chenjie6, lizefan, Zhang Kui, stable

From: Zhang Kui <kyler.zhangkui@huawei.com>

Newsgroups: gmane.linux.kernel.cgroups, gmane.linux.kernel

test case:
    # cat test.sh
    mkdir rootdir
    mount -t cgroup xxx rootdir -o cpu

    mkdir rootdir/0

    rmdir rootdir/0
    umount rootdir

    rmdir rootdir
    # ./test.sh
    # cat /proc/cgroups
    #subsys_name    hierarchy       num_cgroups     enabled
    cpuset  0       1       1
    cpu     1       1       1
    cpuacct 0       1       1
    blkio   0       1       1
    devices 0       1       1
    freezer 0       1       1
    debug   0       1       1

The rootdir's cgroup_root is not released after it is umounted, the cpu
subsystem hierarchy id is not zero.
After that, can not mount other subsystem except cpu on the folder
rootdir.
It is because "rmdir rootdir/0" real action is done in workqueue,
the sub-cgroup "0" has not beend delete from the root->cgrp.self.children
during running "umount rootdir".

Fix this by checking whether cgroup_root has online child on umounting.

Cc: <stable@vger.kernel.org> # 4.1.y+
Signed-off-by: Zhang Kui <kyler.zhangkui@huawei.com>
---
 kernel/cgroup.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index f1603c1..ec6aecc 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2147,6 +2147,13 @@ static void cgroup_kill_sb(struct super_block *sb)
 {
 	struct kernfs_root *kf_root = kernfs_root_from_sb(sb);
 	struct cgroup_root *root = cgroup_root_from_kf(kf_root);
+	struct cgroup *child;
+	int live_child = 0;
+
+	mutex_lock(&cgroup_mutex);
+	cgroup_for_each_live_child(child, &root->cgrp) {
+		live_child++;
+	}
 
 	/*
 	 * If @root doesn't have any mounts or children, start killing it.
@@ -2155,12 +2162,12 @@ static void cgroup_kill_sb(struct super_block *sb)
 	 *
 	 * And don't kill the default root.
 	 */
-	if (!list_empty(&root->cgrp.self.children) ||
-	    root == &cgrp_dfl_root)
-		cgroup_put(&root->cgrp);
+	if (live_child || root == &cgrp_dfl_root)
+	cgroup_put(&root->cgrp);
 	else
 		percpu_ref_kill(&root->cgrp.self.refcnt);
 
+	mutex_unlock(&cgroup_mutex);
 	kernfs_kill_sb(sb);
 }
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] cgroup: bug fix of cgroup_root object was not released after cgroup umounted
  2015-12-14 11:45 ` kyler.zhangkui
  (?)
@ 2015-12-14 19:51 ` Tejun Heo
  -1 siblings, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2015-12-14 19:51 UTC (permalink / raw)
  To: kyler.zhangkui; +Cc: cgroups, zhihui.gao, chenjie6, lizefan, stable

Hello, Zhang.

On Mon, Dec 14, 2015 at 07:45:54PM +0800, kyler.zhangkui@huawei.com wrote:
> @@ -2147,6 +2147,13 @@ static void cgroup_kill_sb(struct super_block *sb)
>  {
>  	struct kernfs_root *kf_root = kernfs_root_from_sb(sb);
>  	struct cgroup_root *root = cgroup_root_from_kf(kf_root);
> +	struct cgroup *child;
> +	int live_child = 0;
> +
> +	mutex_lock(&cgroup_mutex);
> +	cgroup_for_each_live_child(child, &root->cgrp) {
> +		live_child++;
> +	}
>  
>  	/*
>  	 * If @root doesn't have any mounts or children, start killing it.
> @@ -2155,12 +2162,12 @@ static void cgroup_kill_sb(struct super_block *sb)
>  	 *
>  	 * And don't kill the default root.
>  	 */
> -	if (!list_empty(&root->cgrp.self.children) ||
> -	    root == &cgrp_dfl_root)
> -		cgroup_put(&root->cgrp);
> +	if (live_child || root == &cgrp_dfl_root)
> +	cgroup_put(&root->cgrp);
>  	else
>  		percpu_ref_kill(&root->cgrp.self.refcnt);
>  
> +	mutex_unlock(&cgroup_mutex);
>  	kernfs_kill_sb(sb);

I don't know.  With the above change, we might fail remounting with
the same option for some controllers which keep residual objects
around.  Changing controller associations has never been supported
correctly and I don't think it'll ever be.  I have no objection to
improving it but this has the potential to regress use cases which
would be more common.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-12-14 19:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-14 11:45 [PATCH] cgroup: bug fix of cgroup_root object was not released after cgroup umounted kyler.zhangkui
2015-12-14 11:45 ` kyler.zhangkui
2015-12-14 19:51 ` Tejun Heo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.