cgroup: move cgroup->subsys[] assignment to online_css()
Currently, css (cgroup_subsys_state) lifetime is tied to that of the
associated cgroup.  With the planned unified hierarchy, css's will be
dynamically created and destroyed within the lifetime of a cgroup.  To
enable such usages, css's will be individually RCU protected instead
of being tied to the cgroup.
In preparation, this patch moves cgroup->subsys[] assignment from
init_css() to online_css().  As this means that a newly initialized
css should be remembered separately and that cgroup_css() returns NULL
between init and online, cgroup_create() is updated so that it stores
newly created css's in a local array css_ar[] and
cgroup_init/load_subsys() are updated to use local variable @css
instead of using cgroup_css().  This change also slightly simplifies
error path of cgroup_create().
While this patch changes when cgroup->subsys[] is initialized, this
change isn't visible to subsystems or userland.
v2: This patch wasn't updated accordingly after the previous "cgroup:
    reorganize css init / exit paths" was updated leading to missing a
    css_ar[] conversion in cgroup_create() and thus boot failure.  Fix
    it.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								623f926b05
							
						
					
				
			
			
				commit
				
					
						ae7f164a09
					
				
			
		
					 1 changed files with 11 additions and 10 deletions
				
			
		|  | @ -4321,7 +4321,6 @@ static void init_css(struct cgroup_subsys_state *css, struct cgroup_subsys *ss, | ||||||
| 		css->flags |= CSS_ROOT; | 		css->flags |= CSS_ROOT; | ||||||
| 
 | 
 | ||||||
| 	BUG_ON(cgroup_css(cgrp, ss->subsys_id)); | 	BUG_ON(cgroup_css(cgrp, ss->subsys_id)); | ||||||
| 	rcu_assign_pointer(cgrp->subsys[ss->subsys_id], css); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* invoke ->css_online() on a new CSS and mark it online if successful */ | /* invoke ->css_online() on a new CSS and mark it online if successful */ | ||||||
|  | @ -4334,8 +4333,10 @@ static int online_css(struct cgroup_subsys_state *css) | ||||||
| 
 | 
 | ||||||
| 	if (ss->css_online) | 	if (ss->css_online) | ||||||
| 		ret = ss->css_online(css); | 		ret = ss->css_online(css); | ||||||
| 	if (!ret) | 	if (!ret) { | ||||||
| 		css->flags |= CSS_ONLINE; | 		css->flags |= CSS_ONLINE; | ||||||
|  | 		rcu_assign_pointer(css->cgroup->subsys[ss->subsys_id], css); | ||||||
|  | 	} | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -4366,6 +4367,7 @@ static void offline_css(struct cgroup_subsys_state *css) | ||||||
| static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | ||||||
| 			     umode_t mode) | 			     umode_t mode) | ||||||
| { | { | ||||||
|  | 	struct cgroup_subsys_state *css_ar[CGROUP_SUBSYS_COUNT] = { }; | ||||||
| 	struct cgroup *cgrp; | 	struct cgroup *cgrp; | ||||||
| 	struct cgroup_name *name; | 	struct cgroup_name *name; | ||||||
| 	struct cgroupfs_root *root = parent->root; | 	struct cgroupfs_root *root = parent->root; | ||||||
|  | @ -4433,12 +4435,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | ||||||
| 			err = PTR_ERR(css); | 			err = PTR_ERR(css); | ||||||
| 			goto err_free_all; | 			goto err_free_all; | ||||||
| 		} | 		} | ||||||
|  | 		css_ar[ss->subsys_id] = css; | ||||||
| 
 | 
 | ||||||
| 		err = percpu_ref_init(&css->refcnt, css_release); | 		err = percpu_ref_init(&css->refcnt, css_release); | ||||||
| 		if (err) { | 		if (err) | ||||||
| 			ss->css_free(css); |  | ||||||
| 			goto err_free_all; | 			goto err_free_all; | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		init_css(css, ss, cgrp); | 		init_css(css, ss, cgrp); | ||||||
| 
 | 
 | ||||||
|  | @ -4467,7 +4468,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | ||||||
| 
 | 
 | ||||||
| 	/* each css holds a ref to the cgroup's dentry and the parent css */ | 	/* each css holds a ref to the cgroup's dentry and the parent css */ | ||||||
| 	for_each_root_subsys(root, ss) { | 	for_each_root_subsys(root, ss) { | ||||||
| 		struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); | 		struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; | ||||||
| 
 | 
 | ||||||
| 		dget(dentry); | 		dget(dentry); | ||||||
| 		percpu_ref_get(&css->parent->refcnt); | 		percpu_ref_get(&css->parent->refcnt); | ||||||
|  | @ -4478,7 +4479,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | ||||||
| 
 | 
 | ||||||
| 	/* creation succeeded, notify subsystems */ | 	/* creation succeeded, notify subsystems */ | ||||||
| 	for_each_root_subsys(root, ss) { | 	for_each_root_subsys(root, ss) { | ||||||
| 		struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); | 		struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; | ||||||
| 
 | 
 | ||||||
| 		err = online_css(css); | 		err = online_css(css); | ||||||
| 		if (err) | 		if (err) | ||||||
|  | @ -4511,7 +4512,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | ||||||
| 
 | 
 | ||||||
| err_free_all: | err_free_all: | ||||||
| 	for_each_root_subsys(root, ss) { | 	for_each_root_subsys(root, ss) { | ||||||
| 		struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); | 		struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; | ||||||
| 
 | 
 | ||||||
| 		if (css) { | 		if (css) { | ||||||
| 			percpu_ref_cancel_init(&css->refcnt); | 			percpu_ref_cancel_init(&css->refcnt); | ||||||
|  | @ -4793,7 +4794,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | ||||||
| 	 * need to invoke fork callbacks here. */ | 	 * need to invoke fork callbacks here. */ | ||||||
| 	BUG_ON(!list_empty(&init_task.tasks)); | 	BUG_ON(!list_empty(&init_task.tasks)); | ||||||
| 
 | 
 | ||||||
| 	BUG_ON(online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id))); | 	BUG_ON(online_css(css)); | ||||||
| 
 | 
 | ||||||
| 	mutex_unlock(&cgroup_mutex); | 	mutex_unlock(&cgroup_mutex); | ||||||
| 
 | 
 | ||||||
|  | @ -4897,7 +4898,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) | ||||||
| 	} | 	} | ||||||
| 	write_unlock(&css_set_lock); | 	write_unlock(&css_set_lock); | ||||||
| 
 | 
 | ||||||
| 	ret = online_css(cgroup_css(cgroup_dummy_top, ss->subsys_id)); | 	ret = online_css(css); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		goto err_unload; | 		goto err_unload; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tejun Heo
				Tejun Heo