stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] cgroup: fix error return value in cgroup_mount()
       [not found] <1390923125-4369-1-git-send-email-tj@kernel.org>
@ 2014-01-28 15:32 ` Tejun Heo
  2014-01-29  3:36   ` Li Zefan
  2014-01-28 15:32 ` [PATCH 2/4] cgroup: fix error return from cgroup_create() Tejun Heo
  2014-01-28 15:32 ` [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit() Tejun Heo
  2 siblings, 1 reply; 6+ messages in thread
From: Tejun Heo @ 2014-01-28 15:32 UTC (permalink / raw)
  To: lizefan; +Cc: containers, cgroups, linux-kernel, Tejun Heo, stable

When cgroup_mount() fails to allocate an id for the root, it didn't
set ret before jumping to unlock_drop ending up returning 0 after a
failure.  Fix it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org
---
 kernel/cgroup.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e2f46ba..364aeb22 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1566,10 +1566,10 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 		mutex_lock(&cgroup_mutex);
 		mutex_lock(&cgroup_root_mutex);
 
-		root_cgrp->id = idr_alloc(&root->cgroup_idr, root_cgrp,
-					   0, 1, GFP_KERNEL);
-		if (root_cgrp->id < 0)
+		ret = idr_alloc(&root->cgroup_idr, root_cgrp, 0, 1, GFP_KERNEL);
+		if (ret < 0)
 			goto unlock_drop;
+		root_cgrp->id = ret;
 
 		/* Check for name clashes with existing mounts */
 		ret = -EBUSY;
-- 
1.8.5.3


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

* [PATCH 2/4] cgroup: fix error return from cgroup_create()
       [not found] <1390923125-4369-1-git-send-email-tj@kernel.org>
  2014-01-28 15:32 ` [PATCH 1/4] cgroup: fix error return value in cgroup_mount() Tejun Heo
@ 2014-01-28 15:32 ` Tejun Heo
  2014-01-29  3:37   ` Li Zefan
  2014-01-28 15:32 ` [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit() Tejun Heo
  2 siblings, 1 reply; 6+ messages in thread
From: Tejun Heo @ 2014-01-28 15:32 UTC (permalink / raw)
  To: lizefan; +Cc: containers, cgroups, linux-kernel, Tejun Heo, stable

cgroup_create() was returning 0 after allocation failures.  Fix it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org
---
 kernel/cgroup.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 364aeb22..2e9f12a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4158,7 +4158,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	struct cgroup *cgrp;
 	struct cgroup_name *name;
 	struct cgroupfs_root *root = parent->root;
-	int ssid, err = 0;
+	int ssid, err;
 	struct cgroup_subsys *ss;
 	struct super_block *sb = root->sb;
 
@@ -4168,8 +4168,10 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		return -ENOMEM;
 
 	name = cgroup_alloc_name(dentry);
-	if (!name)
+	if (!name) {
+		err = -ENOMEM;
 		goto err_free_cgrp;
+	}
 	rcu_assign_pointer(cgrp->name, name);
 
 	/*
@@ -4177,8 +4179,10 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	 * a half-baked cgroup.
 	 */
 	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
-	if (cgrp->id < 0)
+	if (cgrp->id < 0) {
+		err = -ENOMEM;
 		goto err_free_name;
+	}
 
 	/*
 	 * Only live parents can have children.  Note that the liveliness
-- 
1.8.5.3


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

* [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit()
       [not found] <1390923125-4369-1-git-send-email-tj@kernel.org>
  2014-01-28 15:32 ` [PATCH 1/4] cgroup: fix error return value in cgroup_mount() Tejun Heo
  2014-01-28 15:32 ` [PATCH 2/4] cgroup: fix error return from cgroup_create() Tejun Heo
@ 2014-01-28 15:32 ` Tejun Heo
  2014-01-29  3:37   ` Li Zefan
  2 siblings, 1 reply; 6+ messages in thread
From: Tejun Heo @ 2014-01-28 15:32 UTC (permalink / raw)
  To: lizefan; +Cc: containers, cgroups, linux-kernel, Tejun Heo, stable

cgroup_cfts_commit() walks the cgroup hierarchy that the target
subsystem is attached to and tries to apply the file changes.  Due to
the convolution with inode locking, it can't keep cgroup_mutex locked
while iterating.  It currently holds only RCU read lock around the
actual iteration and then pins the found cgroup using dget().

Unfortunately, this is incorrect.  Although the iteration does check
cgroup_is_dead() before invoking dget(), there's nothing which
prevents the dentry from going away inbetween.  Note that this is
different from the usual css iterations where css_tryget() is used to
pin the css - css_tryget() tests whether the css can be pinned and
fails if not.

The problem can be solved by simply holding cgroup_mutex instead of
RCU read lock around the iteration, which actually reduces LOC.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: stable@vger.kernel.org
---
 kernel/cgroup.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 2e9f12a..b0e030f 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2763,10 +2763,7 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
 	 */
 	update_before = cgroup_serial_nr_next;
 
-	mutex_unlock(&cgroup_mutex);
-
 	/* add/rm files for all cgroups created before */
-	rcu_read_lock();
 	css_for_each_descendant_pre(css, cgroup_css(root, ss)) {
 		struct cgroup *cgrp = css->cgroup;
 
@@ -2775,23 +2772,19 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
 
 		inode = cgrp->dentry->d_inode;
 		dget(cgrp->dentry);
-		rcu_read_unlock();
-
 		dput(prev);
 		prev = cgrp->dentry;
 
+		mutex_unlock(&cgroup_mutex);
 		mutex_lock(&inode->i_mutex);
 		mutex_lock(&cgroup_mutex);
 		if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
 			ret = cgroup_addrm_files(cgrp, cfts, is_add);
-		mutex_unlock(&cgroup_mutex);
 		mutex_unlock(&inode->i_mutex);
-
-		rcu_read_lock();
 		if (ret)
 			break;
 	}
-	rcu_read_unlock();
+	mutex_unlock(&cgroup_mutex);
 	dput(prev);
 	deactivate_super(sb);
 	return ret;
-- 
1.8.5.3


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

* Re: [PATCH 1/4] cgroup: fix error return value in cgroup_mount()
  2014-01-28 15:32 ` [PATCH 1/4] cgroup: fix error return value in cgroup_mount() Tejun Heo
@ 2014-01-29  3:36   ` Li Zefan
  0 siblings, 0 replies; 6+ messages in thread
From: Li Zefan @ 2014-01-29  3:36 UTC (permalink / raw)
  To: Tejun Heo; +Cc: containers, cgroups, linux-kernel, stable

On 2014/1/28 23:32, Tejun Heo wrote:
> When cgroup_mount() fails to allocate an id for the root, it didn't
> set ret before jumping to unlock_drop ending up returning 0 after a
> failure.  Fix it.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: stable@vger.kernel.org

Acked-by: Li Zefan <lizefan@huawei.com>


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

* Re: [PATCH 2/4] cgroup: fix error return from cgroup_create()
  2014-01-28 15:32 ` [PATCH 2/4] cgroup: fix error return from cgroup_create() Tejun Heo
@ 2014-01-29  3:37   ` Li Zefan
  0 siblings, 0 replies; 6+ messages in thread
From: Li Zefan @ 2014-01-29  3:37 UTC (permalink / raw)
  To: Tejun Heo; +Cc: containers, cgroups, linux-kernel, stable

On 2014/1/28 23:32, Tejun Heo wrote:
> cgroup_create() was returning 0 after allocation failures.  Fix it.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: stable@vger.kernel.org

Acked-by: Li Zefan <lizefan@huawei.com>

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

* Re: [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit()
  2014-01-28 15:32 ` [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit() Tejun Heo
@ 2014-01-29  3:37   ` Li Zefan
  0 siblings, 0 replies; 6+ messages in thread
From: Li Zefan @ 2014-01-29  3:37 UTC (permalink / raw)
  To: Tejun Heo; +Cc: containers, cgroups, linux-kernel, stable

On 2014/1/28 23:32, Tejun Heo wrote:
> cgroup_cfts_commit() walks the cgroup hierarchy that the target
> subsystem is attached to and tries to apply the file changes.  Due to
> the convolution with inode locking, it can't keep cgroup_mutex locked
> while iterating.  It currently holds only RCU read lock around the
> actual iteration and then pins the found cgroup using dget().
> 
> Unfortunately, this is incorrect.  Although the iteration does check
> cgroup_is_dead() before invoking dget(), there's nothing which
> prevents the dentry from going away inbetween.  Note that this is
> different from the usual css iterations where css_tryget() is used to
> pin the css - css_tryget() tests whether the css can be pinned and
> fails if not.
> 
> The problem can be solved by simply holding cgroup_mutex instead of
> RCU read lock around the iteration, which actually reduces LOC.
> 
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: stable@vger.kernel.org

Good catch!

Acked-by: Li Zefan <lizefan@huawei.com>

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

end of thread, other threads:[~2014-01-29  3:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1390923125-4369-1-git-send-email-tj@kernel.org>
2014-01-28 15:32 ` [PATCH 1/4] cgroup: fix error return value in cgroup_mount() Tejun Heo
2014-01-29  3:36   ` Li Zefan
2014-01-28 15:32 ` [PATCH 2/4] cgroup: fix error return from cgroup_create() Tejun Heo
2014-01-29  3:37   ` Li Zefan
2014-01-28 15:32 ` [PATCH 3/4] cgroup: fix locking in cgroup_cfts_commit() Tejun Heo
2014-01-29  3:37   ` Li Zefan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).