diff options
author | Tejun Heo <tj@kernel.org> | 2016-03-03 09:57:58 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2016-03-03 09:57:58 -0500 |
commit | 6cd0f5bbaf594f40a97d01dbc565dda41f30d37c (patch) | |
tree | 425f8c38aeb24e944d2a0fac9b59b075e396d509 | |
parent | 20b454a61fba59be13de52b4493898583ea26d20 (diff) |
cgroup: separate out interface file creation from css creation
Currently, interface files are created when a css is created depending
on whether @visible is set. This patch separates out the two into
separate steps to help code refactoring and eventually allow cgroups
which aren't visible through cgroup fs.
Move css_populate_dir() out of create_css() and drop @visible. While
at it, rename the function to css_create() for consistency.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Zefan Li <lizefan@huawei.com>
-rw-r--r-- | kernel/cgroup.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 5d452e7fcb4f..4178e45becb4 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -222,8 +222,8 @@ static struct cftype cgroup_legacy_base_files[]; | |||
222 | static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask); | 222 | static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask); |
223 | static void css_task_iter_advance(struct css_task_iter *it); | 223 | static void css_task_iter_advance(struct css_task_iter *it); |
224 | static int cgroup_destroy_locked(struct cgroup *cgrp); | 224 | static int cgroup_destroy_locked(struct cgroup *cgrp); |
225 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss, | 225 | static struct cgroup_subsys_state *css_create(struct cgroup *cgrp, |
226 | bool visible); | 226 | struct cgroup_subsys *ss); |
227 | static void css_release(struct percpu_ref *ref); | 227 | static void css_release(struct percpu_ref *ref); |
228 | static void kill_css(struct cgroup_subsys_state *css); | 228 | static void kill_css(struct cgroup_subsys_state *css); |
229 | static int cgroup_addrm_files(struct cgroup_subsys_state *css, | 229 | static int cgroup_addrm_files(struct cgroup_subsys_state *css, |
@@ -3082,14 +3082,26 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
3082 | */ | 3082 | */ |
3083 | do_each_subsys_mask(ss, ssid, enable) { | 3083 | do_each_subsys_mask(ss, ssid, enable) { |
3084 | cgroup_for_each_live_child(child, cgrp) { | 3084 | cgroup_for_each_live_child(child, cgrp) { |
3085 | if (css_enable & (1 << ssid)) | 3085 | if (css_enable & (1 << ssid)) { |
3086 | ret = create_css(child, ss, | 3086 | struct cgroup_subsys_state *css; |
3087 | cgrp->subtree_control & (1 << ssid)); | 3087 | |
3088 | else | 3088 | css = css_create(child, ss); |
3089 | if (IS_ERR(css)) { | ||
3090 | ret = PTR_ERR(css); | ||
3091 | goto err_undo_css; | ||
3092 | } | ||
3093 | |||
3094 | if (cgrp->subtree_control & (1 << ssid)) { | ||
3095 | ret = css_populate_dir(css, NULL); | ||
3096 | if (ret) | ||
3097 | goto err_undo_css; | ||
3098 | } | ||
3099 | } else { | ||
3089 | ret = css_populate_dir(cgroup_css(child, ss), | 3100 | ret = css_populate_dir(cgroup_css(child, ss), |
3090 | NULL); | 3101 | NULL); |
3091 | if (ret) | 3102 | if (ret) |
3092 | goto err_undo_css; | 3103 | goto err_undo_css; |
3104 | } | ||
3093 | } | 3105 | } |
3094 | } while_each_subsys_mask(); | 3106 | } while_each_subsys_mask(); |
3095 | 3107 | ||
@@ -4717,7 +4729,9 @@ static void css_release_work_fn(struct work_struct *work) | |||
4717 | * Those are supported by RCU protecting clearing of | 4729 | * Those are supported by RCU protecting clearing of |
4718 | * cgrp->kn->priv backpointer. | 4730 | * cgrp->kn->priv backpointer. |
4719 | */ | 4731 | */ |
4720 | RCU_INIT_POINTER(*(void __rcu __force **)&cgrp->kn->priv, NULL); | 4732 | if (cgrp->kn) |
4733 | RCU_INIT_POINTER(*(void __rcu __force **)&cgrp->kn->priv, | ||
4734 | NULL); | ||
4721 | } | 4735 | } |
4722 | 4736 | ||
4723 | mutex_unlock(&cgroup_mutex); | 4737 | mutex_unlock(&cgroup_mutex); |
@@ -4801,17 +4815,16 @@ static void offline_css(struct cgroup_subsys_state *css) | |||
4801 | } | 4815 | } |
4802 | 4816 | ||
4803 | /** | 4817 | /** |
4804 | * create_css - create a cgroup_subsys_state | 4818 | * css_create - create a cgroup_subsys_state |
4805 | * @cgrp: the cgroup new css will be associated with | 4819 | * @cgrp: the cgroup new css will be associated with |
4806 | * @ss: the subsys of new css | 4820 | * @ss: the subsys of new css |
4807 | * @visible: whether to create control knobs for the new css or not | ||
4808 | * | 4821 | * |
4809 | * Create a new css associated with @cgrp - @ss pair. On success, the new | 4822 | * Create a new css associated with @cgrp - @ss pair. On success, the new |
4810 | * css is online and installed in @cgrp with all interface files created if | 4823 | * css is online and installed in @cgrp. This function doesn't create the |
4811 | * @visible. Returns 0 on success, -errno on failure. | 4824 | * interface files. Returns 0 on success, -errno on failure. |
4812 | */ | 4825 | */ |
4813 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss, | 4826 | static struct cgroup_subsys_state *css_create(struct cgroup *cgrp, |
4814 | bool visible) | 4827 | struct cgroup_subsys *ss) |
4815 | { | 4828 | { |
4816 | struct cgroup *parent = cgroup_parent(cgrp); | 4829 | struct cgroup *parent = cgroup_parent(cgrp); |
4817 | struct cgroup_subsys_state *parent_css = cgroup_css(parent, ss); | 4830 | struct cgroup_subsys_state *parent_css = cgroup_css(parent, ss); |
@@ -4822,7 +4835,7 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss, | |||
4822 | 4835 | ||
4823 | css = ss->css_alloc(parent_css); | 4836 | css = ss->css_alloc(parent_css); |
4824 | if (IS_ERR(css)) | 4837 | if (IS_ERR(css)) |
4825 | return PTR_ERR(css); | 4838 | return css; |
4826 | 4839 | ||
4827 | init_and_link_css(css, ss, cgrp); | 4840 | init_and_link_css(css, ss, cgrp); |
4828 | 4841 | ||
@@ -4835,12 +4848,6 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss, | |||
4835 | goto err_free_percpu_ref; | 4848 | goto err_free_percpu_ref; |
4836 | css->id = err; | 4849 | css->id = err; |
4837 | 4850 | ||
4838 | if (visible) { | ||
4839 | err = css_populate_dir(css, NULL); | ||
4840 | if (err) | ||
4841 | goto err_free_id; | ||
4842 | } | ||
4843 | |||
4844 | /* @css is ready to be brought online now, make it visible */ | 4851 | /* @css is ready to be brought online now, make it visible */ |
4845 | list_add_tail_rcu(&css->sibling, &parent_css->children); | 4852 | list_add_tail_rcu(&css->sibling, &parent_css->children); |
4846 | cgroup_idr_replace(&ss->css_idr, css, css->id); | 4853 | cgroup_idr_replace(&ss->css_idr, css, css->id); |
@@ -4858,18 +4865,16 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss, | |||
4858 | ss->warned_broken_hierarchy = true; | 4865 | ss->warned_broken_hierarchy = true; |
4859 | } | 4866 | } |
4860 | 4867 | ||
4861 | return 0; | 4868 | return css; |
4862 | 4869 | ||
4863 | err_list_del: | 4870 | err_list_del: |
4864 | list_del_rcu(&css->sibling); | 4871 | list_del_rcu(&css->sibling); |
4865 | css_clear_dir(css, NULL); | ||
4866 | err_free_id: | ||
4867 | cgroup_idr_remove(&ss->css_idr, css->id); | 4872 | cgroup_idr_remove(&ss->css_idr, css->id); |
4868 | err_free_percpu_ref: | 4873 | err_free_percpu_ref: |
4869 | percpu_ref_exit(&css->refcnt); | 4874 | percpu_ref_exit(&css->refcnt); |
4870 | err_free_css: | 4875 | err_free_css: |
4871 | call_rcu(&css->rcu_head, css_free_rcu_fn); | 4876 | call_rcu(&css->rcu_head, css_free_rcu_fn); |
4872 | return err; | 4877 | return ERR_PTR(err); |
4873 | } | 4878 | } |
4874 | 4879 | ||
4875 | static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | 4880 | static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, |
@@ -4966,10 +4971,19 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | |||
4966 | 4971 | ||
4967 | /* let's create and online css's */ | 4972 | /* let's create and online css's */ |
4968 | do_each_subsys_mask(ss, ssid, parent->subtree_ss_mask) { | 4973 | do_each_subsys_mask(ss, ssid, parent->subtree_ss_mask) { |
4969 | ret = create_css(cgrp, ss, | 4974 | struct cgroup_subsys_state *css; |
4970 | parent->subtree_control & (1 << ssid)); | 4975 | |
4971 | if (ret) | 4976 | css = css_create(cgrp, ss); |
4977 | if (IS_ERR(css)) { | ||
4978 | ret = PTR_ERR(css); | ||
4972 | goto out_destroy; | 4979 | goto out_destroy; |
4980 | } | ||
4981 | |||
4982 | if (parent->subtree_control & (1 << ssid)) { | ||
4983 | ret = css_populate_dir(css, NULL); | ||
4984 | if (ret) | ||
4985 | goto out_destroy; | ||
4986 | } | ||
4973 | } while_each_subsys_mask(); | 4987 | } while_each_subsys_mask(); |
4974 | 4988 | ||
4975 | /* | 4989 | /* |