Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-3.11-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fix from Tejun Heo:
"During the percpu reference counting update which was merged during
v3.11-rc1, the cgroup destruction path was updated so that a cgroup in
the process of dying may linger on the children list, which was
necessary as the cgroup should still be included in child/descendant
iteration while percpu ref is being killed.

Unfortunately, I forgot to update cgroup destruction path accordingly
and cgroup destruction may fail spuriously with -EBUSY due to
lingering dying children even when there's no live child left - e.g.
"rmdir parent/child parent" will usually fail.

This can be easily fixed by iterating through the children list to
verify that there's no live child left. While this is very late in
the release cycle, this bug is very visible to userland and I believe
the fix is relatively safe.

Thanks Hugh for spotting and providing fix for the issue"

* 'for-3.11-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
cgroup: fix rmdir EBUSY regression in 3.11

+18 -1
+18 -1
kernel/cgroup.c
··· 4480 4480 struct dentry *d = cgrp->dentry; 4481 4481 struct cgroup_event *event, *tmp; 4482 4482 struct cgroup_subsys *ss; 4483 + struct cgroup *child; 4483 4484 bool empty; 4484 4485 4485 4486 lockdep_assert_held(&d->d_inode->i_mutex); ··· 4491 4490 * @cgrp from being removed while __put_css_set() is in progress. 4492 4491 */ 4493 4492 read_lock(&css_set_lock); 4494 - empty = list_empty(&cgrp->cset_links) && list_empty(&cgrp->children); 4493 + empty = list_empty(&cgrp->cset_links); 4495 4494 read_unlock(&css_set_lock); 4495 + if (!empty) 4496 + return -EBUSY; 4497 + 4498 + /* 4499 + * Make sure there's no live children. We can't test ->children 4500 + * emptiness as dead children linger on it while being destroyed; 4501 + * otherwise, "rmdir parent/child parent" may fail with -EBUSY. 4502 + */ 4503 + empty = true; 4504 + rcu_read_lock(); 4505 + list_for_each_entry_rcu(child, &cgrp->children, sibling) { 4506 + empty = cgroup_is_dead(child); 4507 + if (!empty) 4508 + break; 4509 + } 4510 + rcu_read_unlock(); 4496 4511 if (!empty) 4497 4512 return -EBUSY; 4498 4513