diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-11 11:52:49 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-11 11:52:49 -0500 |
commit | 59f5296b51b86718dd6eecf0a268b2f1a1ec0a2d (patch) | |
tree | 0854f2b46c93190b8fb5bb1e0a992f1e5b77320e /kernel/cgroup.c | |
parent | b1664924062393bb048203bd4622e0b1c9e1d328 (diff) |
cgroup: misc preps for kernfs conversion
* Un-inline seq_css(). After kernfs conversion, the function will
need to dereference internal data structures.
* Add cgroup_get/put_root() and replace direct super_block->s_active
manipulatinos with them. These will be converted to kernfs_root
refcnting.
* Add cgroup_get/put() and replace dget/put() on cgrp->dentry with
them. These will be converted to kernfs refcnting.
* Update current_css_set_cg_links_read() to use cgroup_name() instead
of reaching into the dentry name. The end result is the same.
These changes don't make functional differences but will make
transition to kernfs easier.
v2: Rebased on top of 0ab02ca8f887 ("cgroup: protect modifications to
cgroup_idr with cgroup_mutex").
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 85 |
1 files changed, 53 insertions, 32 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 11f7a05e791e..9e9e8fd632d8 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -169,6 +169,7 @@ static int need_forkexit_callback __read_mostly; | |||
169 | 169 | ||
170 | static struct cftype cgroup_base_files[]; | 170 | static struct cftype cgroup_base_files[]; |
171 | 171 | ||
172 | static void cgroup_put(struct cgroup *cgrp); | ||
172 | static void cgroup_destroy_css_killed(struct cgroup *cgrp); | 173 | static void cgroup_destroy_css_killed(struct cgroup *cgrp); |
173 | static int cgroup_destroy_locked(struct cgroup *cgrp); | 174 | static int cgroup_destroy_locked(struct cgroup *cgrp); |
174 | static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[], | 175 | static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[], |
@@ -204,6 +205,13 @@ static inline bool cgroup_is_dead(const struct cgroup *cgrp) | |||
204 | return test_bit(CGRP_DEAD, &cgrp->flags); | 205 | return test_bit(CGRP_DEAD, &cgrp->flags); |
205 | } | 206 | } |
206 | 207 | ||
208 | struct cgroup_subsys_state *seq_css(struct seq_file *seq) | ||
209 | { | ||
210 | struct cgroup_open_file *of = seq->private; | ||
211 | return of->cfe->css; | ||
212 | } | ||
213 | EXPORT_SYMBOL_GPL(seq_css); | ||
214 | |||
207 | /** | 215 | /** |
208 | * cgroup_is_descendant - test ancestry | 216 | * cgroup_is_descendant - test ancestry |
209 | * @cgrp: the cgroup to be tested | 217 | * @cgrp: the cgroup to be tested |
@@ -682,6 +690,16 @@ static struct css_set *find_css_set(struct css_set *old_cset, | |||
682 | return cset; | 690 | return cset; |
683 | } | 691 | } |
684 | 692 | ||
693 | static void cgroup_get_root(struct cgroupfs_root *root) | ||
694 | { | ||
695 | atomic_inc(&root->sb->s_active); | ||
696 | } | ||
697 | |||
698 | static void cgroup_put_root(struct cgroupfs_root *root) | ||
699 | { | ||
700 | deactivate_super(root->sb); | ||
701 | } | ||
702 | |||
685 | /* | 703 | /* |
686 | * Return the cgroup for "task" from the given hierarchy. Must be | 704 | * Return the cgroup for "task" from the given hierarchy. Must be |
687 | * called with cgroup_mutex held. | 705 | * called with cgroup_mutex held. |
@@ -837,18 +855,14 @@ static void cgroup_free_fn(struct work_struct *work) | |||
837 | mutex_unlock(&cgroup_mutex); | 855 | mutex_unlock(&cgroup_mutex); |
838 | 856 | ||
839 | /* | 857 | /* |
840 | * We get a ref to the parent's dentry, and put the ref when | 858 | * We get a ref to the parent, and put the ref when this cgroup is |
841 | * this cgroup is being freed, so it's guaranteed that the | 859 | * being freed, so it's guaranteed that the parent won't be |
842 | * parent won't be destroyed before its children. | 860 | * destroyed before its children. |
843 | */ | 861 | */ |
844 | dput(cgrp->parent->dentry); | 862 | cgroup_put(cgrp->parent); |
845 | 863 | ||
846 | /* | 864 | /* put the root reference that we took when we created the cgroup */ |
847 | * Drop the active superblock reference that we took when we | 865 | cgroup_put_root(cgrp->root); |
848 | * created the cgroup. This will free cgrp->root, if we are | ||
849 | * holding the last reference to @sb. | ||
850 | */ | ||
851 | deactivate_super(cgrp->root->sb); | ||
852 | 866 | ||
853 | cgroup_pidlist_destroy_all(cgrp); | 867 | cgroup_pidlist_destroy_all(cgrp); |
854 | 868 | ||
@@ -866,6 +880,11 @@ static void cgroup_free_rcu(struct rcu_head *head) | |||
866 | queue_work(cgroup_destroy_wq, &cgrp->destroy_work); | 880 | queue_work(cgroup_destroy_wq, &cgrp->destroy_work); |
867 | } | 881 | } |
868 | 882 | ||
883 | static void cgroup_get(struct cgroup *cgrp) | ||
884 | { | ||
885 | dget(cgrp->dentry); | ||
886 | } | ||
887 | |||
869 | static void cgroup_diput(struct dentry *dentry, struct inode *inode) | 888 | static void cgroup_diput(struct dentry *dentry, struct inode *inode) |
870 | { | 889 | { |
871 | /* is dentry a directory ? if so, kfree() associated cgroup */ | 890 | /* is dentry a directory ? if so, kfree() associated cgroup */ |
@@ -899,6 +918,11 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
899 | iput(inode); | 918 | iput(inode); |
900 | } | 919 | } |
901 | 920 | ||
921 | static void cgroup_put(struct cgroup *cgrp) | ||
922 | { | ||
923 | dput(cgrp->dentry); | ||
924 | } | ||
925 | |||
902 | static void remove_dir(struct dentry *d) | 926 | static void remove_dir(struct dentry *d) |
903 | { | 927 | { |
904 | struct dentry *parent = dget(d->d_parent); | 928 | struct dentry *parent = dget(d->d_parent); |
@@ -2724,7 +2748,7 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) | |||
2724 | struct cgroup_subsys *ss = cfts[0].ss; | 2748 | struct cgroup_subsys *ss = cfts[0].ss; |
2725 | struct cgroup *root = &ss->root->top_cgroup; | 2749 | struct cgroup *root = &ss->root->top_cgroup; |
2726 | struct super_block *sb = ss->root->sb; | 2750 | struct super_block *sb = ss->root->sb; |
2727 | struct dentry *prev = NULL; | 2751 | struct cgroup *prev = NULL; |
2728 | struct inode *inode; | 2752 | struct inode *inode; |
2729 | struct cgroup_subsys_state *css; | 2753 | struct cgroup_subsys_state *css; |
2730 | u64 update_before; | 2754 | u64 update_before; |
@@ -2754,9 +2778,10 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) | |||
2754 | continue; | 2778 | continue; |
2755 | 2779 | ||
2756 | inode = cgrp->dentry->d_inode; | 2780 | inode = cgrp->dentry->d_inode; |
2757 | dget(cgrp->dentry); | 2781 | cgroup_get(cgrp); |
2758 | dput(prev); | 2782 | if (prev) |
2759 | prev = cgrp->dentry; | 2783 | cgroup_put(prev); |
2784 | prev = cgrp; | ||
2760 | 2785 | ||
2761 | mutex_unlock(&cgroup_tree_mutex); | 2786 | mutex_unlock(&cgroup_tree_mutex); |
2762 | mutex_lock(&inode->i_mutex); | 2787 | mutex_lock(&inode->i_mutex); |
@@ -2768,8 +2793,8 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) | |||
2768 | break; | 2793 | break; |
2769 | } | 2794 | } |
2770 | mutex_unlock(&cgroup_tree_mutex); | 2795 | mutex_unlock(&cgroup_tree_mutex); |
2771 | dput(prev); | 2796 | cgroup_put(prev); |
2772 | deactivate_super(sb); | 2797 | cgroup_put_root(ss->root); |
2773 | return ret; | 2798 | return ret; |
2774 | } | 2799 | } |
2775 | 2800 | ||
@@ -3863,11 +3888,9 @@ static int cgroup_write_notify_on_release(struct cgroup_subsys_state *css, | |||
3863 | */ | 3888 | */ |
3864 | static void cgroup_dput(struct cgroup *cgrp) | 3889 | static void cgroup_dput(struct cgroup *cgrp) |
3865 | { | 3890 | { |
3866 | struct super_block *sb = cgrp->root->sb; | 3891 | cgroup_get_root(cgrp->root); |
3867 | 3892 | cgroup_put(cgrp); | |
3868 | atomic_inc(&sb->s_active); | 3893 | cgroup_put_root(cgrp->root); |
3869 | dput(cgrp->dentry); | ||
3870 | deactivate_super(sb); | ||
3871 | } | 3894 | } |
3872 | 3895 | ||
3873 | static u64 cgroup_clone_children_read(struct cgroup_subsys_state *css, | 3896 | static u64 cgroup_clone_children_read(struct cgroup_subsys_state *css, |
@@ -4118,7 +4141,7 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss) | |||
4118 | if (err) | 4141 | if (err) |
4119 | goto err_free; | 4142 | goto err_free; |
4120 | 4143 | ||
4121 | dget(cgrp->dentry); | 4144 | cgroup_get(cgrp); |
4122 | css_get(css->parent); | 4145 | css_get(css->parent); |
4123 | 4146 | ||
4124 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && | 4147 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && |
@@ -4197,7 +4220,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4197 | * can be done outside cgroup_mutex, since the sb can't | 4220 | * can be done outside cgroup_mutex, since the sb can't |
4198 | * disappear while someone has an open control file on the | 4221 | * disappear while someone has an open control file on the |
4199 | * fs */ | 4222 | * fs */ |
4200 | atomic_inc(&sb->s_active); | 4223 | cgroup_get_root(root); |
4201 | 4224 | ||
4202 | init_cgroup_housekeeping(cgrp); | 4225 | init_cgroup_housekeeping(cgrp); |
4203 | 4226 | ||
@@ -4231,7 +4254,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4231 | root->number_of_cgroups++; | 4254 | root->number_of_cgroups++; |
4232 | 4255 | ||
4233 | /* hold a ref to the parent's dentry */ | 4256 | /* hold a ref to the parent's dentry */ |
4234 | dget(parent->dentry); | 4257 | cgroup_get(parent); |
4235 | 4258 | ||
4236 | /* | 4259 | /* |
4237 | * @cgrp is now fully operational. If something fails after this | 4260 | * @cgrp is now fully operational. If something fails after this |
@@ -4261,7 +4284,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4261 | err_free_id: | 4284 | err_free_id: |
4262 | idr_remove(&root->cgroup_idr, cgrp->id); | 4285 | idr_remove(&root->cgroup_idr, cgrp->id); |
4263 | /* Release the reference count that we took on the superblock */ | 4286 | /* Release the reference count that we took on the superblock */ |
4264 | deactivate_super(sb); | 4287 | cgroup_put_root(root); |
4265 | err_unlock: | 4288 | err_unlock: |
4266 | mutex_unlock(&cgroup_mutex); | 4289 | mutex_unlock(&cgroup_mutex); |
4267 | err_unlock_tree: | 4290 | err_unlock_tree: |
@@ -4493,7 +4516,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4493 | static void cgroup_destroy_css_killed(struct cgroup *cgrp) | 4516 | static void cgroup_destroy_css_killed(struct cgroup *cgrp) |
4494 | { | 4517 | { |
4495 | struct cgroup *parent = cgrp->parent; | 4518 | struct cgroup *parent = cgrp->parent; |
4496 | struct dentry *d = cgrp->dentry; | ||
4497 | 4519 | ||
4498 | lockdep_assert_held(&cgroup_tree_mutex); | 4520 | lockdep_assert_held(&cgroup_tree_mutex); |
4499 | lockdep_assert_held(&cgroup_mutex); | 4521 | lockdep_assert_held(&cgroup_mutex); |
@@ -4501,7 +4523,7 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp) | |||
4501 | /* delete this cgroup from parent->children */ | 4523 | /* delete this cgroup from parent->children */ |
4502 | list_del_rcu(&cgrp->sibling); | 4524 | list_del_rcu(&cgrp->sibling); |
4503 | 4525 | ||
4504 | dput(d); | 4526 | cgroup_put(cgrp); |
4505 | 4527 | ||
4506 | set_bit(CGRP_RELEASABLE, &parent->flags); | 4528 | set_bit(CGRP_RELEASABLE, &parent->flags); |
4507 | check_for_release(parent); | 4529 | check_for_release(parent); |
@@ -5161,12 +5183,11 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v) | |||
5161 | cset = rcu_dereference(current->cgroups); | 5183 | cset = rcu_dereference(current->cgroups); |
5162 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { | 5184 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { |
5163 | struct cgroup *c = link->cgrp; | 5185 | struct cgroup *c = link->cgrp; |
5164 | const char *name; | 5186 | const char *name = "?"; |
5187 | |||
5188 | if (c != cgroup_dummy_top) | ||
5189 | name = cgroup_name(c); | ||
5165 | 5190 | ||
5166 | if (c->dentry) | ||
5167 | name = c->dentry->d_name.name; | ||
5168 | else | ||
5169 | name = "?"; | ||
5170 | seq_printf(seq, "Root %d group %s\n", | 5191 | seq_printf(seq, "Root %d group %s\n", |
5171 | c->root->hierarchy_id, name); | 5192 | c->root->hierarchy_id, name); |
5172 | } | 5193 | } |