diff options
author | Tejun Heo <tj@kernel.org> | 2014-05-13 12:19:23 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-05-13 12:19:23 -0400 |
commit | 01f6474ce04fffd6282b569ac0a31f4b98d4c82a (patch) | |
tree | b536ea8d57db3c87fbe897db727005db5cf2e8db /kernel | |
parent | e76ecaeef65c497153ceacf59c2e21c070d43f64 (diff) |
cgroup: nest kernfs active protection under cgroup_mutex
After the recent cgroup_kn_lock_live() changes, cgroup_mutex is no
longer nested below kernfs active protection. The two don't have any
relationship now.
This patch nests kernfs active protection under cgroup_mutex. All
cftype operations now require both cgroup_tree_mutex and cgroup_mutex,
temporary cgroup_mutex releases over kernfs operations are removed,
and cgroup_add/rm_cftypes() grab both mutexes.
This makes cgroup_tree_mutex redundant, which will be removed by the
next patch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index b7cd80845f6a..bf1d7ce250ac 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1127,7 +1127,7 @@ static struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn) | |||
1127 | cgrp = kn->parent->priv; | 1127 | cgrp = kn->parent->priv; |
1128 | 1128 | ||
1129 | /* | 1129 | /* |
1130 | * We're gonna grab cgroup_tree_mutex which nests outside kernfs | 1130 | * We're gonna grab cgroup_mutex which nests outside kernfs |
1131 | * active_ref. cgroup liveliness check alone provides enough | 1131 | * active_ref. cgroup liveliness check alone provides enough |
1132 | * protection against removal. Ensure @cgrp stays accessible and | 1132 | * protection against removal. Ensure @cgrp stays accessible and |
1133 | * break the active_ref protection. | 1133 | * break the active_ref protection. |
@@ -1150,6 +1150,7 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft) | |||
1150 | char name[CGROUP_FILE_NAME_MAX]; | 1150 | char name[CGROUP_FILE_NAME_MAX]; |
1151 | 1151 | ||
1152 | lockdep_assert_held(&cgroup_tree_mutex); | 1152 | lockdep_assert_held(&cgroup_tree_mutex); |
1153 | lockdep_assert_held(&cgroup_mutex); | ||
1153 | kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); | 1154 | kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); |
1154 | } | 1155 | } |
1155 | 1156 | ||
@@ -1216,11 +1217,9 @@ static int rebind_subsystems(struct cgroup_root *dst_root, unsigned int ss_mask) | |||
1216 | * Nothing can fail from this point on. Remove files for the | 1217 | * Nothing can fail from this point on. Remove files for the |
1217 | * removed subsystems and rebind each subsystem. | 1218 | * removed subsystems and rebind each subsystem. |
1218 | */ | 1219 | */ |
1219 | mutex_unlock(&cgroup_mutex); | ||
1220 | for_each_subsys(ss, ssid) | 1220 | for_each_subsys(ss, ssid) |
1221 | if (ss_mask & (1 << ssid)) | 1221 | if (ss_mask & (1 << ssid)) |
1222 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); | 1222 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); |
1223 | mutex_lock(&cgroup_mutex); | ||
1224 | 1223 | ||
1225 | for_each_subsys(ss, ssid) { | 1224 | for_each_subsys(ss, ssid) { |
1226 | struct cgroup_root *src_root; | 1225 | struct cgroup_root *src_root; |
@@ -2946,6 +2945,7 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[], | |||
2946 | int ret; | 2945 | int ret; |
2947 | 2946 | ||
2948 | lockdep_assert_held(&cgroup_tree_mutex); | 2947 | lockdep_assert_held(&cgroup_tree_mutex); |
2948 | lockdep_assert_held(&cgroup_mutex); | ||
2949 | 2949 | ||
2950 | for (cft = cfts; cft->name[0] != '\0'; cft++) { | 2950 | for (cft = cfts; cft->name[0] != '\0'; cft++) { |
2951 | /* does cft->flags tell us to skip this file on @cgrp? */ | 2951 | /* does cft->flags tell us to skip this file on @cgrp? */ |
@@ -2981,6 +2981,7 @@ static int cgroup_apply_cftypes(struct cftype *cfts, bool is_add) | |||
2981 | int ret = 0; | 2981 | int ret = 0; |
2982 | 2982 | ||
2983 | lockdep_assert_held(&cgroup_tree_mutex); | 2983 | lockdep_assert_held(&cgroup_tree_mutex); |
2984 | lockdep_assert_held(&cgroup_mutex); | ||
2984 | 2985 | ||
2985 | /* add/rm files for all cgroups created before */ | 2986 | /* add/rm files for all cgroups created before */ |
2986 | css_for_each_descendant_pre(css, cgroup_css(root, ss)) { | 2987 | css_for_each_descendant_pre(css, cgroup_css(root, ss)) { |
@@ -3049,6 +3050,7 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) | |||
3049 | static int cgroup_rm_cftypes_locked(struct cftype *cfts) | 3050 | static int cgroup_rm_cftypes_locked(struct cftype *cfts) |
3050 | { | 3051 | { |
3051 | lockdep_assert_held(&cgroup_tree_mutex); | 3052 | lockdep_assert_held(&cgroup_tree_mutex); |
3053 | lockdep_assert_held(&cgroup_mutex); | ||
3052 | 3054 | ||
3053 | if (!cfts || !cfts[0].ss) | 3055 | if (!cfts || !cfts[0].ss) |
3054 | return -ENOENT; | 3056 | return -ENOENT; |
@@ -3075,7 +3077,9 @@ int cgroup_rm_cftypes(struct cftype *cfts) | |||
3075 | int ret; | 3077 | int ret; |
3076 | 3078 | ||
3077 | mutex_lock(&cgroup_tree_mutex); | 3079 | mutex_lock(&cgroup_tree_mutex); |
3080 | mutex_lock(&cgroup_mutex); | ||
3078 | ret = cgroup_rm_cftypes_locked(cfts); | 3081 | ret = cgroup_rm_cftypes_locked(cfts); |
3082 | mutex_unlock(&cgroup_mutex); | ||
3079 | mutex_unlock(&cgroup_tree_mutex); | 3083 | mutex_unlock(&cgroup_tree_mutex); |
3080 | return ret; | 3084 | return ret; |
3081 | } | 3085 | } |
@@ -3106,12 +3110,14 @@ int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) | |||
3106 | return ret; | 3110 | return ret; |
3107 | 3111 | ||
3108 | mutex_lock(&cgroup_tree_mutex); | 3112 | mutex_lock(&cgroup_tree_mutex); |
3113 | mutex_lock(&cgroup_mutex); | ||
3109 | 3114 | ||
3110 | list_add_tail(&cfts->node, &ss->cfts); | 3115 | list_add_tail(&cfts->node, &ss->cfts); |
3111 | ret = cgroup_apply_cftypes(cfts, true); | 3116 | ret = cgroup_apply_cftypes(cfts, true); |
3112 | if (ret) | 3117 | if (ret) |
3113 | cgroup_rm_cftypes_locked(cfts); | 3118 | cgroup_rm_cftypes_locked(cfts); |
3114 | 3119 | ||
3120 | mutex_unlock(&cgroup_mutex); | ||
3115 | mutex_unlock(&cgroup_tree_mutex); | 3121 | mutex_unlock(&cgroup_tree_mutex); |
3116 | return ret; | 3122 | return ret; |
3117 | } | 3123 | } |
@@ -4445,6 +4451,7 @@ static void css_killed_ref_fn(struct percpu_ref *ref) | |||
4445 | static void kill_css(struct cgroup_subsys_state *css) | 4451 | static void kill_css(struct cgroup_subsys_state *css) |
4446 | { | 4452 | { |
4447 | lockdep_assert_held(&cgroup_tree_mutex); | 4453 | lockdep_assert_held(&cgroup_tree_mutex); |
4454 | lockdep_assert_held(&cgroup_mutex); | ||
4448 | 4455 | ||
4449 | /* | 4456 | /* |
4450 | * This must happen before css is disassociated with its cgroup. | 4457 | * This must happen before css is disassociated with its cgroup. |
@@ -4544,13 +4551,10 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4544 | /* | 4551 | /* |
4545 | * Initiate massacre of all css's. cgroup_destroy_css_killed() | 4552 | * Initiate massacre of all css's. cgroup_destroy_css_killed() |
4546 | * will be invoked to perform the rest of destruction once the | 4553 | * will be invoked to perform the rest of destruction once the |
4547 | * percpu refs of all css's are confirmed to be killed. This | 4554 | * percpu refs of all css's are confirmed to be killed. |
4548 | * involves removing the subsystem's files, drop cgroup_mutex. | ||
4549 | */ | 4555 | */ |
4550 | mutex_unlock(&cgroup_mutex); | ||
4551 | for_each_css(css, ssid, cgrp) | 4556 | for_each_css(css, ssid, cgrp) |
4552 | kill_css(css); | 4557 | kill_css(css); |
4553 | mutex_lock(&cgroup_mutex); | ||
4554 | 4558 | ||
4555 | /* CGRP_DEAD is set, remove from ->release_list for the last time */ | 4559 | /* CGRP_DEAD is set, remove from ->release_list for the last time */ |
4556 | raw_spin_lock(&release_list_lock); | 4560 | raw_spin_lock(&release_list_lock); |
@@ -4567,10 +4571,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4567 | if (!cgrp->nr_css) | 4571 | if (!cgrp->nr_css) |
4568 | cgroup_destroy_css_killed(cgrp); | 4572 | cgroup_destroy_css_killed(cgrp); |
4569 | 4573 | ||
4570 | /* remove @cgrp directory along with the base files */ | 4574 | /* |
4571 | mutex_unlock(&cgroup_mutex); | 4575 | * Remove @cgrp directory along with the base files. @cgrp has an |
4572 | kernfs_remove(cgrp->kn); /* @cgrp has an extra ref on its kn */ | 4576 | * extra ref on its kn. |
4573 | mutex_lock(&cgroup_mutex); | 4577 | */ |
4578 | kernfs_remove(cgrp->kn); | ||
4574 | 4579 | ||
4575 | return 0; | 4580 | return 0; |
4576 | }; | 4581 | }; |