提交 4ac06017 编写于 作者: T Tejun Heo

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: NTejun Heo <tj@kernel.org>
Acked-by: NLi Zefan <lizefan@huawei.com>
上级 ace2bee8
...@@ -976,7 +976,9 @@ static int rebind_subsystems(struct cgroupfs_root *root, ...@@ -976,7 +976,9 @@ static int rebind_subsystems(struct cgroupfs_root *root,
* Nothing can fail from this point on. Remove files for the * Nothing can fail from this point on. Remove files for the
* removed subsystems and rebind each subsystem. * removed subsystems and rebind each subsystem.
*/ */
mutex_unlock(&cgroup_mutex);
cgroup_clear_dir(cgrp, removed_mask); cgroup_clear_dir(cgrp, removed_mask);
mutex_lock(&cgroup_mutex);
for_each_subsys(ss, i) { for_each_subsys(ss, i) {
unsigned long bit = 1UL << i; unsigned long bit = 1UL << i;
...@@ -2696,10 +2698,11 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) ...@@ -2696,10 +2698,11 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
u64 update_before; u64 update_before;
int ret = 0; int ret = 0;
mutex_unlock(&cgroup_mutex);
/* %NULL @cfts indicates abort and don't bother if @ss isn't attached */ /* %NULL @cfts indicates abort and don't bother if @ss isn't attached */
if (!cfts || ss->root == &cgroup_dummy_root || if (!cfts || ss->root == &cgroup_dummy_root ||
!atomic_inc_not_zero(&sb->s_active)) { !atomic_inc_not_zero(&sb->s_active)) {
mutex_unlock(&cgroup_mutex);
mutex_unlock(&cgroup_tree_mutex); mutex_unlock(&cgroup_tree_mutex);
return 0; return 0;
} }
...@@ -2723,18 +2726,15 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add) ...@@ -2723,18 +2726,15 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
dput(prev); dput(prev);
prev = cgrp->dentry; prev = cgrp->dentry;
mutex_unlock(&cgroup_mutex);
mutex_unlock(&cgroup_tree_mutex); mutex_unlock(&cgroup_tree_mutex);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
mutex_lock(&cgroup_tree_mutex); mutex_lock(&cgroup_tree_mutex);
mutex_lock(&cgroup_mutex);
if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
ret = cgroup_addrm_files(cgrp, cfts, is_add); ret = cgroup_addrm_files(cgrp, cfts, is_add);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
if (ret) if (ret)
break; break;
} }
mutex_unlock(&cgroup_mutex);
mutex_unlock(&cgroup_tree_mutex); mutex_unlock(&cgroup_tree_mutex);
dput(prev); dput(prev);
deactivate_super(sb); deactivate_super(sb);
...@@ -4387,10 +4387,13 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) ...@@ -4387,10 +4387,13 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
/* /*
* Initiate massacre of all css's. cgroup_destroy_css_killed() * Initiate massacre of all css's. cgroup_destroy_css_killed()
* will be invoked to perform the rest of destruction once the * will be invoked to perform the rest of destruction once the
* percpu refs of all css's are confirmed to be killed. * percpu refs of all css's are confirmed to be killed. This
* involves removing the subsystem's files, drop cgroup_mutex.
*/ */
mutex_unlock(&cgroup_mutex);
for_each_css(css, ssid, cgrp) for_each_css(css, ssid, cgrp)
kill_css(css); kill_css(css);
mutex_lock(&cgroup_mutex);
/* /*
* Mark @cgrp dead. This prevents further task migration and child * Mark @cgrp dead. This prevents further task migration and child
...@@ -4421,9 +4424,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) ...@@ -4421,9 +4424,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
* puts the base ref but we aren't quite done with @cgrp yet, so * puts the base ref but we aren't quite done with @cgrp yet, so
* hold onto it. * hold onto it.
*/ */
mutex_unlock(&cgroup_mutex);
cgroup_addrm_files(cgrp, cgroup_base_files, false); cgroup_addrm_files(cgrp, cgroup_base_files, false);
dget(d); dget(d);
cgroup_d_remove_dir(d); cgroup_d_remove_dir(d);
mutex_lock(&cgroup_mutex);
return 0; return 0;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册