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.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fixes from Tejun Heo:
"Two fixes. One fixes a bug in the error path of cgroup_create(). The
other changes cgrp->id lifetime rule so that the id doesn't get
recycled before all controller states are destroyed. This premature
id recycling made memcg malfunction"

* 'for-3.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
cgroup: don't recycle cgroup id until all csses' have been destroyed
cgroup: fix cgroup_create() error handling path

+32 -18
+32 -18
kernel/cgroup.c
··· 890 890 struct cgroup *cgrp = dentry->d_fsdata; 891 891 892 892 BUG_ON(!(cgroup_is_dead(cgrp))); 893 + 894 + /* 895 + * XXX: cgrp->id is only used to look up css's. As cgroup 896 + * and css's lifetimes will be decoupled, it should be made 897 + * per-subsystem and moved to css->id so that lookups are 898 + * successful until the target css is released. 899 + */ 900 + idr_remove(&cgrp->root->cgroup_idr, cgrp->id); 901 + cgrp->id = -1; 902 + 893 903 call_rcu(&cgrp->rcu_head, cgroup_free_rcu); 894 904 } else { 895 905 struct cfent *cfe = __d_cfe(dentry); ··· 4278 4268 struct cgroup_subsys_state *css = 4279 4269 container_of(ref, struct cgroup_subsys_state, refcnt); 4280 4270 4271 + rcu_assign_pointer(css->cgroup->subsys[css->ss->subsys_id], NULL); 4281 4272 call_rcu(&css->rcu_head, css_free_rcu_fn); 4282 4273 } 4283 4274 ··· 4437 4426 list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); 4438 4427 root->number_of_cgroups++; 4439 4428 4440 - /* each css holds a ref to the cgroup's dentry and the parent css */ 4441 - for_each_root_subsys(root, ss) { 4442 - struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; 4443 - 4444 - dget(dentry); 4445 - css_get(css->parent); 4446 - } 4447 - 4448 4429 /* hold a ref to the parent's dentry */ 4449 4430 dget(parent->dentry); 4450 4431 ··· 4447 4444 err = online_css(css); 4448 4445 if (err) 4449 4446 goto err_destroy; 4447 + 4448 + /* each css holds a ref to the cgroup's dentry and parent css */ 4449 + dget(dentry); 4450 + css_get(css->parent); 4451 + 4452 + /* mark it consumed for error path */ 4453 + css_ar[ss->subsys_id] = NULL; 4450 4454 4451 4455 if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && 4452 4456 parent->parent) { ··· 4501 4491 return err; 4502 4492 4503 4493 err_destroy: 4494 + for_each_root_subsys(root, ss) { 4495 + struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; 4496 + 4497 + if (css) { 4498 + percpu_ref_cancel_init(&css->refcnt); 4499 + ss->css_free(css); 4500 + } 4501 + } 4504 4502 cgroup_destroy_locked(cgrp); 4505 4503 mutex_unlock(&cgroup_mutex); 4506 4504 mutex_unlock(&dentry->d_inode->i_mutex); ··· 4670 4652 * will be invoked to perform the rest of destruction once the 4671 4653 * percpu refs of all css's are confirmed to be killed. 4672 4654 */ 4673 - for_each_root_subsys(cgrp->root, ss) 4674 - kill_css(cgroup_css(cgrp, ss)); 4655 + for_each_root_subsys(cgrp->root, ss) { 4656 + struct cgroup_subsys_state *css = cgroup_css(cgrp, ss); 4657 + 4658 + if (css) 4659 + kill_css(css); 4660 + } 4675 4661 4676 4662 /* 4677 4663 * Mark @cgrp dead. This prevents further task migration and child ··· 4743 4721 4744 4722 /* delete this cgroup from parent->children */ 4745 4723 list_del_rcu(&cgrp->sibling); 4746 - 4747 - /* 4748 - * We should remove the cgroup object from idr before its grace 4749 - * period starts, so we won't be looking up a cgroup while the 4750 - * cgroup is being freed. 4751 - */ 4752 - idr_remove(&cgrp->root->cgroup_idr, cgrp->id); 4753 - cgrp->id = -1; 4754 4724 4755 4725 dput(d); 4756 4726