aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-02-11 11:52:47 -0500
committerTejun Heo <tj@kernel.org>2014-02-11 11:52:47 -0500
commit4ac0601744eb86e982fbdadde35f1945f7ce5882 (patch)
tree887f0cbc2853802ad113b87f0d2c5b764e2619ce /kernel/cgroup.c
parentace2bee8135a3dc725958b8d08c55ee9df813d39 (diff)
cgroup: release cgroup_mutex over file removals
Now that cftypes and all tree modification operations are protected by cgroup_tree_mutex, we can drop cgroup_mutex while deleting files and directories. Drop cgroup_mutex over removals. This doesn't make any noticeable difference now but is to help kernfs conversion. In kernfs, removals are sync points which drain in-flight operations as those operations would grab cgroup_mutex, trying to delete under cgroup_mutex would deadlock. This can be resolved by just holding the outer cgroup_tree_mutex which nests outside both kernfs active reference and 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.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index cb20d12cb096..d28cf75f33c1 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -976,7 +976,9 @@ static int rebind_subsystems(struct cgroupfs_root *root,
976 * Nothing can fail from this point on. Remove files for the 976 * Nothing can fail from this point on. Remove files for the
977 * removed subsystems and rebind each subsystem. 977 * removed subsystems and rebind each subsystem.
978 */ 978 */
979 mutex_unlock(&cgroup_mutex);
979 cgroup_clear_dir(cgrp, removed_mask); 980 cgroup_clear_dir(cgrp, removed_mask);
981 mutex_lock(&cgroup_mutex);
980 982
981 for_each_subsys(ss, i) { 983 for_each_subsys(ss, i) {
982 unsigned long bit = 1UL << i; 984 unsigned long bit = 1UL << i;
@@ -2696,10 +2698,11 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2696 u64 update_before; 2698 u64 update_before;
2697 int ret = 0; 2699 int ret = 0;
2698 2700
2701 mutex_unlock(&cgroup_mutex);
2702
2699 /* %NULL @cfts indicates abort and don't bother if @ss isn't attached */ 2703 /* %NULL @cfts indicates abort and don't bother if @ss isn't attached */
2700 if (!cfts || ss->root == &cgroup_dummy_root || 2704 if (!cfts || ss->root == &cgroup_dummy_root ||
2701 !atomic_inc_not_zero(&sb->s_active)) { 2705 !atomic_inc_not_zero(&sb->s_active)) {
2702 mutex_unlock(&cgroup_mutex);
2703 mutex_unlock(&cgroup_tree_mutex); 2706 mutex_unlock(&cgroup_tree_mutex);
2704 return 0; 2707 return 0;
2705 } 2708 }
@@ -2723,18 +2726,15 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2723 dput(prev); 2726 dput(prev);
2724 prev = cgrp->dentry; 2727 prev = cgrp->dentry;
2725 2728
2726 mutex_unlock(&cgroup_mutex);
2727 mutex_unlock(&cgroup_tree_mutex); 2729 mutex_unlock(&cgroup_tree_mutex);
2728 mutex_lock(&inode->i_mutex); 2730 mutex_lock(&inode->i_mutex);
2729 mutex_lock(&cgroup_tree_mutex); 2731 mutex_lock(&cgroup_tree_mutex);
2730 mutex_lock(&cgroup_mutex);
2731 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) 2732 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
2732 ret = cgroup_addrm_files(cgrp, cfts, is_add); 2733 ret = cgroup_addrm_files(cgrp, cfts, is_add);
2733 mutex_unlock(&inode->i_mutex); 2734 mutex_unlock(&inode->i_mutex);
2734 if (ret) 2735 if (ret)
2735 break; 2736 break;
2736 } 2737 }
2737 mutex_unlock(&cgroup_mutex);
2738 mutex_unlock(&cgroup_tree_mutex); 2738 mutex_unlock(&cgroup_tree_mutex);
2739 dput(prev); 2739 dput(prev);
2740 deactivate_super(sb); 2740 deactivate_super(sb);
@@ -4387,10 +4387,13 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4387 /* 4387 /*
4388 * Initiate massacre of all css's. cgroup_destroy_css_killed() 4388 * Initiate massacre of all css's. cgroup_destroy_css_killed()
4389 * will be invoked to perform the rest of destruction once the 4389 * will be invoked to perform the rest of destruction once the
4390 * percpu refs of all css's are confirmed to be killed. 4390 * percpu refs of all css's are confirmed to be killed. This
4391 * involves removing the subsystem's files, drop cgroup_mutex.
4391 */ 4392 */
4393 mutex_unlock(&cgroup_mutex);
4392 for_each_css(css, ssid, cgrp) 4394 for_each_css(css, ssid, cgrp)
4393 kill_css(css); 4395 kill_css(css);
4396 mutex_lock(&cgroup_mutex);
4394 4397
4395 /* 4398 /*
4396 * Mark @cgrp dead. This prevents further task migration and child 4399 * Mark @cgrp dead. This prevents further task migration and child
@@ -4421,9 +4424,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4421 * puts the base ref but we aren't quite done with @cgrp yet, so 4424 * puts the base ref but we aren't quite done with @cgrp yet, so
4422 * hold onto it. 4425 * hold onto it.
4423 */ 4426 */
4427 mutex_unlock(&cgroup_mutex);
4424 cgroup_addrm_files(cgrp, cgroup_base_files, false); 4428 cgroup_addrm_files(cgrp, cgroup_base_files, false);
4425 dget(d); 4429 dget(d);
4426 cgroup_d_remove_dir(d); 4430 cgroup_d_remove_dir(d);
4431 mutex_lock(&cgroup_mutex);
4427 4432
4428 return 0; 4433 return 0;
4429}; 4434};