cgroup: make cgroup hold onto its kernfs_node
cgroup currently releases its kernfs_node when it gets removed. While not buggy, this makes cgroup->kn access rules complicated than necessary and leads to things like get/put protection around kernfs_remove() in cgroup_destroy_locked(). In addition, we want to use kernfs_name/path() and friends but also want to be able to determine a cgroup's name between removal and release. This patch makes cgroup hold onto its kernfs_node until freed so that cgroup->kn is always accessible. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
This commit is contained in:
		
							parent
							
								
									21a2d3430b
								
							
						
					
					
						commit
						6f30558f37
					
				| @ -957,6 +957,8 @@ static void cgroup_free_fn(struct work_struct *work) | ||||
| 
 | ||||
| 	cgroup_pidlist_destroy_all(cgrp); | ||||
| 
 | ||||
| 	kernfs_put(cgrp->kn); | ||||
| 
 | ||||
| 	kfree(rcu_dereference_raw(cgrp->name)); | ||||
| 	kfree(cgrp); | ||||
| } | ||||
| @ -3786,6 +3788,12 @@ static long cgroup_create(struct cgroup *parent, const char *name_str, | ||||
| 	} | ||||
| 	cgrp->kn = kn; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * This extra ref will be put in cgroup_free_fn() and guarantees | ||||
| 	 * that @cgrp->kn is always accessible. | ||||
| 	 */ | ||||
| 	kernfs_get(kn); | ||||
| 
 | ||||
| 	cgrp->serial_nr = cgroup_serial_nr_next++; | ||||
| 
 | ||||
| 	/* allocation complete, commit to creation */ | ||||
| @ -3966,7 +3974,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | ||||
| { | ||||
| 	struct cgroup *child; | ||||
| 	struct cgroup_subsys_state *css; | ||||
| 	struct kernfs_node *kn; | ||||
| 	bool empty; | ||||
| 	int ssid; | ||||
| 
 | ||||
| @ -4044,13 +4051,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | ||||
| 	 * clearing of cgrp->kn->priv backpointer, which should happen | ||||
| 	 * after all files under it have been removed. | ||||
| 	 */ | ||||
| 	kn = cgrp->kn; | ||||
| 	kernfs_get(kn); | ||||
| 
 | ||||
| 	kernfs_remove(cgrp->kn); | ||||
| 
 | ||||
| 	kernfs_remove(cgrp->kn);	/* @cgrp has an extra ref on its kn */ | ||||
| 	RCU_INIT_POINTER(*(void __rcu __force **)&cgrp->kn->priv, NULL); | ||||
| 	kernfs_put(kn); | ||||
| 
 | ||||
| 	mutex_lock(&cgroup_mutex); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user