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
commitace2bee8135a3dc725958b8d08c55ee9df813d39 (patch)
tree8221115e4d100e566a9405bb25db79b0a751c480 /kernel/cgroup.c
parent5a17f543ed6808e9085063277fe46795dea484bd (diff)
cgroup: introduce cgroup_tree_mutex
Currently cgroup uses combination of inode->i_mutex'es and cgroup_mutex for synchronization. With the scheduled kernfs conversion, i_mutex'es will be removed. Unfortunately, just using cgroup_mutex isn't possible. All kernfs file and syscall operations, most of which require grabbing cgroup_mutex, will be called with kernfs active ref held and, if we try to perform kernfs removals under cgroup_mutex, it can deadlock as kernfs_remove() tries to drain the target node. Let's introduce a new outer mutex, cgroup_tree_mutex, which protects stuff used during hierarchy changing operations - cftypes and all the operations which may affect the cgroupfs. It also covers css association and iteration. This allows cgroup_css(), for_each_css() and other css iterators to be called under cgroup_tree_mutex. The new mutex will nest above both kernfs's active ref protection and cgroup_mutex. By protecting tree modifications with a separate outer mutex, we can get rid of the forementioned deadlock condition. Actual file additions and removals now require cgroup_tree_mutex instead of cgroup_mutex. Currently, cgroup_tree_mutex is never used without cgroup_mutex; however, we'll soon add hierarchy modification sections which are only protected by cgroup_tree_mutex. In the future, we might want to make the locking more granular by better splitting the coverages of the two mutexes. For now, this should do. 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.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index fc2db071d95e..cb20d12cb096 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -68,6 +68,15 @@
68#define CGROUP_PIDLIST_DESTROY_DELAY HZ 68#define CGROUP_PIDLIST_DESTROY_DELAY HZ
69 69
70/* 70/*
71 * cgroup_tree_mutex nests above cgroup_mutex and protects cftypes, file
72 * creation/removal and hierarchy changing operations including cgroup
73 * creation, removal, css association and controller rebinding. This outer
74 * lock is needed mainly to resolve the circular dependency between kernfs
75 * active ref and cgroup_mutex. cgroup_tree_mutex nests above both.
76 */
77static DEFINE_MUTEX(cgroup_tree_mutex);
78
79/*
71 * cgroup_mutex is the master lock. Any modification to cgroup or its 80 * cgroup_mutex is the master lock. Any modification to cgroup or its
72 * hierarchy must be performed while holding it. 81 * hierarchy must be performed while holding it.
73 */ 82 */
@@ -84,10 +93,11 @@ static DEFINE_MUTEX(cgroup_mutex);
84 */ 93 */
85static DEFINE_SPINLOCK(release_agent_path_lock); 94static DEFINE_SPINLOCK(release_agent_path_lock);
86 95
87#define cgroup_assert_mutex_or_rcu_locked() \ 96#define cgroup_assert_mutexes_or_rcu_locked() \
88 rcu_lockdep_assert(rcu_read_lock_held() || \ 97 rcu_lockdep_assert(rcu_read_lock_held() || \
98 lockdep_is_held(&cgroup_tree_mutex) || \
89 lockdep_is_held(&cgroup_mutex), \ 99 lockdep_is_held(&cgroup_mutex), \
90 "cgroup_mutex or RCU read lock required"); 100 "cgroup_[tree_]mutex or RCU read lock required");
91 101
92/* 102/*
93 * cgroup destruction makes heavy use of work items and there can be a lot 103 * cgroup destruction makes heavy use of work items and there can be a lot
@@ -179,7 +189,8 @@ static struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp,
179{ 189{
180 if (ss) 190 if (ss)
181 return rcu_dereference_check(cgrp->subsys[ss->id], 191 return rcu_dereference_check(cgrp->subsys[ss->id],
182 lockdep_is_held(&cgroup_mutex)); 192 lockdep_is_held(&cgroup_tree_mutex) ||
193 lockdep_is_held(&cgroup_mutex));
183 else 194 else
184 return &cgrp->dummy_css; 195 return &cgrp->dummy_css;
185} 196}
@@ -235,6 +246,7 @@ static int notify_on_release(const struct cgroup *cgrp)
235 for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT; (ssid)++) \ 246 for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT; (ssid)++) \
236 if (!((css) = rcu_dereference_check( \ 247 if (!((css) = rcu_dereference_check( \
237 (cgrp)->subsys[(ssid)], \ 248 (cgrp)->subsys[(ssid)], \
249 lockdep_is_held(&cgroup_tree_mutex) || \
238 lockdep_is_held(&cgroup_mutex)))) { } \ 250 lockdep_is_held(&cgroup_mutex)))) { } \
239 else 251 else
240 252
@@ -883,7 +895,7 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
883 struct cfent *cfe; 895 struct cfent *cfe;
884 896
885 lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex); 897 lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex);
886 lockdep_assert_held(&cgroup_mutex); 898 lockdep_assert_held(&cgroup_tree_mutex);
887 899
888 /* 900 /*
889 * If we're doing cleanup due to failure of cgroup_create(), 901 * If we're doing cleanup due to failure of cgroup_create(),
@@ -948,7 +960,8 @@ static int rebind_subsystems(struct cgroupfs_root *root,
948 struct cgroup_subsys *ss; 960 struct cgroup_subsys *ss;
949 int i, ret; 961 int i, ret;
950 962
951 BUG_ON(!mutex_is_locked(&cgroup_mutex)); 963 lockdep_assert_held(&cgroup_tree_mutex);
964 lockdep_assert_held(&cgroup_mutex);
952 965
953 /* Check that any added subsystems are currently free */ 966 /* Check that any added subsystems are currently free */
954 for_each_subsys(ss, i) 967 for_each_subsys(ss, i)
@@ -1220,6 +1233,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
1220 } 1233 }
1221 1234
1222 mutex_lock(&cgrp->dentry->d_inode->i_mutex); 1235 mutex_lock(&cgrp->dentry->d_inode->i_mutex);
1236 mutex_lock(&cgroup_tree_mutex);
1223 mutex_lock(&cgroup_mutex); 1237 mutex_lock(&cgroup_mutex);
1224 1238
1225 /* See what subsystems are wanted */ 1239 /* See what subsystems are wanted */
@@ -1263,6 +1277,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
1263 kfree(opts.release_agent); 1277 kfree(opts.release_agent);
1264 kfree(opts.name); 1278 kfree(opts.name);
1265 mutex_unlock(&cgroup_mutex); 1279 mutex_unlock(&cgroup_mutex);
1280 mutex_unlock(&cgroup_tree_mutex);
1266 mutex_unlock(&cgrp->dentry->d_inode->i_mutex); 1281 mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
1267 return ret; 1282 return ret;
1268} 1283}
@@ -1494,6 +1509,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1494 inode = sb->s_root->d_inode; 1509 inode = sb->s_root->d_inode;
1495 1510
1496 mutex_lock(&inode->i_mutex); 1511 mutex_lock(&inode->i_mutex);
1512 mutex_lock(&cgroup_tree_mutex);
1497 mutex_lock(&cgroup_mutex); 1513 mutex_lock(&cgroup_mutex);
1498 1514
1499 ret = idr_alloc(&root->cgroup_idr, root_cgrp, 0, 1, GFP_KERNEL); 1515 ret = idr_alloc(&root->cgroup_idr, root_cgrp, 0, 1, GFP_KERNEL);
@@ -1568,6 +1584,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1568 BUG_ON(root->number_of_cgroups != 1); 1584 BUG_ON(root->number_of_cgroups != 1);
1569 1585
1570 mutex_unlock(&cgroup_mutex); 1586 mutex_unlock(&cgroup_mutex);
1587 mutex_unlock(&cgroup_tree_mutex);
1571 mutex_unlock(&inode->i_mutex); 1588 mutex_unlock(&inode->i_mutex);
1572 } else { 1589 } else {
1573 /* 1590 /*
@@ -1598,6 +1615,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1598 unlock_drop: 1615 unlock_drop:
1599 cgroup_exit_root_id(root); 1616 cgroup_exit_root_id(root);
1600 mutex_unlock(&cgroup_mutex); 1617 mutex_unlock(&cgroup_mutex);
1618 mutex_unlock(&cgroup_tree_mutex);
1601 mutex_unlock(&inode->i_mutex); 1619 mutex_unlock(&inode->i_mutex);
1602 drop_new_super: 1620 drop_new_super:
1603 deactivate_locked_super(sb); 1621 deactivate_locked_super(sb);
@@ -1620,6 +1638,7 @@ static void cgroup_kill_sb(struct super_block *sb)
1620 BUG_ON(!list_empty(&cgrp->children)); 1638 BUG_ON(!list_empty(&cgrp->children));
1621 1639
1622 mutex_lock(&cgrp->dentry->d_inode->i_mutex); 1640 mutex_lock(&cgrp->dentry->d_inode->i_mutex);
1641 mutex_lock(&cgroup_tree_mutex);
1623 mutex_lock(&cgroup_mutex); 1642 mutex_lock(&cgroup_mutex);
1624 1643
1625 /* Rebind all subsystems back to the default hierarchy */ 1644 /* Rebind all subsystems back to the default hierarchy */
@@ -1650,6 +1669,7 @@ static void cgroup_kill_sb(struct super_block *sb)
1650 cgroup_exit_root_id(root); 1669 cgroup_exit_root_id(root);
1651 1670
1652 mutex_unlock(&cgroup_mutex); 1671 mutex_unlock(&cgroup_mutex);
1672 mutex_unlock(&cgroup_tree_mutex);
1653 mutex_unlock(&cgrp->dentry->d_inode->i_mutex); 1673 mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
1654 1674
1655 simple_xattrs_free(&cgrp->xattrs); 1675 simple_xattrs_free(&cgrp->xattrs);
@@ -2625,7 +2645,7 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
2625 int ret; 2645 int ret;
2626 2646
2627 lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex); 2647 lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex);
2628 lockdep_assert_held(&cgroup_mutex); 2648 lockdep_assert_held(&cgroup_tree_mutex);
2629 2649
2630 for (cft = cfts; cft->name[0] != '\0'; cft++) { 2650 for (cft = cfts; cft->name[0] != '\0'; cft++) {
2631 /* does cft->flags tell us to skip this file on @cgrp? */ 2651 /* does cft->flags tell us to skip this file on @cgrp? */
@@ -2659,6 +2679,7 @@ static void cgroup_cfts_prepare(void)
2659 * Instead, we use css_for_each_descendant_pre() and drop RCU read 2679 * Instead, we use css_for_each_descendant_pre() and drop RCU read
2660 * lock before calling cgroup_addrm_files(). 2680 * lock before calling cgroup_addrm_files().
2661 */ 2681 */
2682 mutex_lock(&cgroup_tree_mutex);
2662 mutex_lock(&cgroup_mutex); 2683 mutex_lock(&cgroup_mutex);
2663} 2684}
2664 2685
@@ -2679,6 +2700,7 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2679 if (!cfts || ss->root == &cgroup_dummy_root || 2700 if (!cfts || ss->root == &cgroup_dummy_root ||
2680 !atomic_inc_not_zero(&sb->s_active)) { 2701 !atomic_inc_not_zero(&sb->s_active)) {
2681 mutex_unlock(&cgroup_mutex); 2702 mutex_unlock(&cgroup_mutex);
2703 mutex_unlock(&cgroup_tree_mutex);
2682 return 0; 2704 return 0;
2683 } 2705 }
2684 2706
@@ -2702,7 +2724,9 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2702 prev = cgrp->dentry; 2724 prev = cgrp->dentry;
2703 2725
2704 mutex_unlock(&cgroup_mutex); 2726 mutex_unlock(&cgroup_mutex);
2727 mutex_unlock(&cgroup_tree_mutex);
2705 mutex_lock(&inode->i_mutex); 2728 mutex_lock(&inode->i_mutex);
2729 mutex_lock(&cgroup_tree_mutex);
2706 mutex_lock(&cgroup_mutex); 2730 mutex_lock(&cgroup_mutex);
2707 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) 2731 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
2708 ret = cgroup_addrm_files(cgrp, cfts, is_add); 2732 ret = cgroup_addrm_files(cgrp, cfts, is_add);
@@ -2711,6 +2735,7 @@ static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2711 break; 2735 break;
2712 } 2736 }
2713 mutex_unlock(&cgroup_mutex); 2737 mutex_unlock(&cgroup_mutex);
2738 mutex_unlock(&cgroup_tree_mutex);
2714 dput(prev); 2739 dput(prev);
2715 deactivate_super(sb); 2740 deactivate_super(sb);
2716 return ret; 2741 return ret;
@@ -2856,7 +2881,7 @@ css_next_child(struct cgroup_subsys_state *pos_css,
2856 struct cgroup *cgrp = parent_css->cgroup; 2881 struct cgroup *cgrp = parent_css->cgroup;
2857 struct cgroup *next; 2882 struct cgroup *next;
2858 2883
2859 cgroup_assert_mutex_or_rcu_locked(); 2884 cgroup_assert_mutexes_or_rcu_locked();
2860 2885
2861 /* 2886 /*
2862 * @pos could already have been removed. Once a cgroup is removed, 2887 * @pos could already have been removed. Once a cgroup is removed,
@@ -2914,7 +2939,7 @@ css_next_descendant_pre(struct cgroup_subsys_state *pos,
2914{ 2939{
2915 struct cgroup_subsys_state *next; 2940 struct cgroup_subsys_state *next;
2916 2941
2917 cgroup_assert_mutex_or_rcu_locked(); 2942 cgroup_assert_mutexes_or_rcu_locked();
2918 2943
2919 /* if first iteration, visit @root */ 2944 /* if first iteration, visit @root */
2920 if (!pos) 2945 if (!pos)
@@ -2955,7 +2980,7 @@ css_rightmost_descendant(struct cgroup_subsys_state *pos)
2955{ 2980{
2956 struct cgroup_subsys_state *last, *tmp; 2981 struct cgroup_subsys_state *last, *tmp;
2957 2982
2958 cgroup_assert_mutex_or_rcu_locked(); 2983 cgroup_assert_mutexes_or_rcu_locked();
2959 2984
2960 do { 2985 do {
2961 last = pos; 2986 last = pos;
@@ -3003,7 +3028,7 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
3003{ 3028{
3004 struct cgroup_subsys_state *next; 3029 struct cgroup_subsys_state *next;
3005 3030
3006 cgroup_assert_mutex_or_rcu_locked(); 3031 cgroup_assert_mutexes_or_rcu_locked();
3007 3032
3008 /* if first iteration, visit leftmost descendant which may be @root */ 3033 /* if first iteration, visit leftmost descendant which may be @root */
3009 if (!pos) 3034 if (!pos)
@@ -3977,6 +4002,7 @@ static int online_css(struct cgroup_subsys_state *css)
3977 struct cgroup_subsys *ss = css->ss; 4002 struct cgroup_subsys *ss = css->ss;
3978 int ret = 0; 4003 int ret = 0;
3979 4004
4005 lockdep_assert_held(&cgroup_tree_mutex);
3980 lockdep_assert_held(&cgroup_mutex); 4006 lockdep_assert_held(&cgroup_mutex);
3981 4007
3982 if (ss->css_online) 4008 if (ss->css_online)
@@ -3994,6 +4020,7 @@ static void offline_css(struct cgroup_subsys_state *css)
3994{ 4020{
3995 struct cgroup_subsys *ss = css->ss; 4021 struct cgroup_subsys *ss = css->ss;
3996 4022
4023 lockdep_assert_held(&cgroup_tree_mutex);
3997 lockdep_assert_held(&cgroup_mutex); 4024 lockdep_assert_held(&cgroup_mutex);
3998 4025
3999 if (!(css->flags & CSS_ONLINE)) 4026 if (!(css->flags & CSS_ONLINE))
@@ -4093,6 +4120,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4093 } 4120 }
4094 rcu_assign_pointer(cgrp->name, name); 4121 rcu_assign_pointer(cgrp->name, name);
4095 4122
4123 mutex_lock(&cgroup_tree_mutex);
4124
4096 /* 4125 /*
4097 * Only live parents can have children. Note that the liveliness 4126 * Only live parents can have children. Note that the liveliness
4098 * check isn't strictly necessary because cgroup_mkdir() and 4127 * check isn't strictly necessary because cgroup_mkdir() and
@@ -4102,7 +4131,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4102 */ 4131 */
4103 if (!cgroup_lock_live_group(parent)) { 4132 if (!cgroup_lock_live_group(parent)) {
4104 err = -ENODEV; 4133 err = -ENODEV;
4105 goto err_free_name; 4134 goto err_unlock_tree;
4106 } 4135 }
4107 4136
4108 /* 4137 /*
@@ -4176,6 +4205,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4176 } 4205 }
4177 4206
4178 mutex_unlock(&cgroup_mutex); 4207 mutex_unlock(&cgroup_mutex);
4208 mutex_unlock(&cgroup_tree_mutex);
4179 mutex_unlock(&cgrp->dentry->d_inode->i_mutex); 4209 mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
4180 4210
4181 return 0; 4211 return 0;
@@ -4186,7 +4216,8 @@ err_free_id:
4186 deactivate_super(sb); 4216 deactivate_super(sb);
4187err_unlock: 4217err_unlock:
4188 mutex_unlock(&cgroup_mutex); 4218 mutex_unlock(&cgroup_mutex);
4189err_free_name: 4219err_unlock_tree:
4220 mutex_unlock(&cgroup_tree_mutex);
4190 kfree(rcu_dereference_raw(cgrp->name)); 4221 kfree(rcu_dereference_raw(cgrp->name));
4191err_free_cgrp: 4222err_free_cgrp:
4192 kfree(cgrp); 4223 kfree(cgrp);
@@ -4195,6 +4226,7 @@ err_free_cgrp:
4195err_destroy: 4226err_destroy:
4196 cgroup_destroy_locked(cgrp); 4227 cgroup_destroy_locked(cgrp);
4197 mutex_unlock(&cgroup_mutex); 4228 mutex_unlock(&cgroup_mutex);
4229 mutex_unlock(&cgroup_tree_mutex);
4198 mutex_unlock(&dentry->d_inode->i_mutex); 4230 mutex_unlock(&dentry->d_inode->i_mutex);
4199 return err; 4231 return err;
4200} 4232}
@@ -4217,6 +4249,7 @@ static void css_killed_work_fn(struct work_struct *work)
4217 container_of(work, struct cgroup_subsys_state, destroy_work); 4249 container_of(work, struct cgroup_subsys_state, destroy_work);
4218 struct cgroup *cgrp = css->cgroup; 4250 struct cgroup *cgrp = css->cgroup;
4219 4251
4252 mutex_lock(&cgroup_tree_mutex);
4220 mutex_lock(&cgroup_mutex); 4253 mutex_lock(&cgroup_mutex);
4221 4254
4222 /* 4255 /*
@@ -4234,6 +4267,7 @@ static void css_killed_work_fn(struct work_struct *work)
4234 cgroup_destroy_css_killed(cgrp); 4267 cgroup_destroy_css_killed(cgrp);
4235 4268
4236 mutex_unlock(&cgroup_mutex); 4269 mutex_unlock(&cgroup_mutex);
4270 mutex_unlock(&cgroup_tree_mutex);
4237 4271
4238 /* 4272 /*
4239 * Put the css refs from kill_css(). Each css holds an extra 4273 * Put the css refs from kill_css(). Each css holds an extra
@@ -4321,6 +4355,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4321 int ssid; 4355 int ssid;
4322 4356
4323 lockdep_assert_held(&d->d_inode->i_mutex); 4357 lockdep_assert_held(&d->d_inode->i_mutex);
4358 lockdep_assert_held(&cgroup_tree_mutex);
4324 lockdep_assert_held(&cgroup_mutex); 4359 lockdep_assert_held(&cgroup_mutex);
4325 4360
4326 /* 4361 /*
@@ -4407,6 +4442,7 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp)
4407 struct cgroup *parent = cgrp->parent; 4442 struct cgroup *parent = cgrp->parent;
4408 struct dentry *d = cgrp->dentry; 4443 struct dentry *d = cgrp->dentry;
4409 4444
4445 lockdep_assert_held(&cgroup_tree_mutex);
4410 lockdep_assert_held(&cgroup_mutex); 4446 lockdep_assert_held(&cgroup_mutex);
4411 4447
4412 /* delete this cgroup from parent->children */ 4448 /* delete this cgroup from parent->children */
@@ -4422,9 +4458,11 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
4422{ 4458{
4423 int ret; 4459 int ret;
4424 4460
4461 mutex_lock(&cgroup_tree_mutex);
4425 mutex_lock(&cgroup_mutex); 4462 mutex_lock(&cgroup_mutex);
4426 ret = cgroup_destroy_locked(dentry->d_fsdata); 4463 ret = cgroup_destroy_locked(dentry->d_fsdata);
4427 mutex_unlock(&cgroup_mutex); 4464 mutex_unlock(&cgroup_mutex);
4465 mutex_unlock(&cgroup_tree_mutex);
4428 4466
4429 return ret; 4467 return ret;
4430} 4468}
@@ -4454,6 +4492,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4454 4492
4455 printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name); 4493 printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name);
4456 4494
4495 mutex_lock(&cgroup_tree_mutex);
4457 mutex_lock(&cgroup_mutex); 4496 mutex_lock(&cgroup_mutex);
4458 4497
4459 /* init base cftset */ 4498 /* init base cftset */
@@ -4482,6 +4521,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4482 BUG_ON(online_css(css)); 4521 BUG_ON(online_css(css));
4483 4522
4484 mutex_unlock(&cgroup_mutex); 4523 mutex_unlock(&cgroup_mutex);
4524 mutex_unlock(&cgroup_tree_mutex);
4485} 4525}
4486 4526
4487/** 4527/**
@@ -5021,7 +5061,7 @@ struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss)
5021{ 5061{
5022 struct cgroup *cgrp; 5062 struct cgroup *cgrp;
5023 5063
5024 cgroup_assert_mutex_or_rcu_locked(); 5064 cgroup_assert_mutexes_or_rcu_locked();
5025 5065
5026 cgrp = idr_find(&ss->root->cgroup_idr, id); 5066 cgrp = idr_find(&ss->root->cgroup_idr, id);
5027 if (cgrp) 5067 if (cgrp)