aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-19 11:13:37 -0500
committerTejun Heo <tj@kernel.org>2012-11-19 11:13:37 -0500
commitb8a2df6a5b576d04f78f54abf254c283527d8bbc (patch)
tree6a49e4105d3bb3d813378d72ebf67c08d719d0de /kernel/cgroup.c
parentd19e19de48aa0b90c56cd93c8a46ebac46273429 (diff)
cgroup: use mutex_trylock() when grabbing i_mutex of a new cgroup directory
All cgroup directory i_mutexes nest outside cgroup_mutex; however, new directory creation is a special case. A new cgroup directory is created while holding cgroup_mutex. Populating the new directory requires both the new directory's i_mutex and cgroup_mutex. Because all directory i_mutexes nest outside cgroup_mutex, grabbing both requires releasing cgroup_mutex first, which isn't a good idea as the new cgroup isn't yet ready to be manipulated by other cgroup opreations. This is worked around by grabbing the new directory's i_mutex while holding cgroup_mutex before making it visible. As there's no other user at that point, grabbing the i_mutex under cgroup_mutex can't lead to deadlock. cgroup_create_file() was using I_MUTEX_CHILD to tell lockdep not to worry about the reverse locking order; however, this creates pseudo locking dependency cgroup_mutex -> I_MUTEX_CHILD, which isn't true - all directory i_mutexes are still nested outside cgroup_mutex. This pseudo locking dependency can lead to spurious lockdep warnings. Use mutex_trylock() instead. This will always succeed and lockdep doesn't create any locking dependency for it. 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.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 166b5141f3d4..c53f42e31704 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2657,9 +2657,15 @@ static int cgroup_create_file(struct dentry *dentry, umode_t mode,
2657 inc_nlink(inode); 2657 inc_nlink(inode);
2658 inc_nlink(dentry->d_parent->d_inode); 2658 inc_nlink(dentry->d_parent->d_inode);
2659 2659
2660 /* start with the directory inode held, so that we can 2660 /*
2661 * populate it without racing with another mkdir */ 2661 * Control reaches here with cgroup_mutex held.
2662 mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); 2662 * @inode->i_mutex should nest outside cgroup_mutex but we
2663 * want to populate it immediately without releasing
2664 * cgroup_mutex. As @inode isn't visible to anyone else
2665 * yet, trylock will always succeed without affecting
2666 * lockdep checks.
2667 */
2668 WARN_ON_ONCE(!mutex_trylock(&inode->i_mutex));
2663 } else if (S_ISREG(mode)) { 2669 } else if (S_ISREG(mode)) {
2664 inode->i_size = 0; 2670 inode->i_size = 0;
2665 inode->i_fop = &cgroup_file_operations; 2671 inode->i_fop = &cgroup_file_operations;