diff options
| author | Tejun Heo <tj@kernel.org> | 2017-06-14 16:01:41 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2017-06-14 16:01:41 -0400 |
| commit | b6053d40e3387c916d56d319ba6bfdb2c42a67c7 (patch) | |
| tree | 5f45453c0f4675950f56ee4ef1fdb16057eb6552 /kernel/cgroup | |
| parent | 2866c0b4cf25274040f0b4cc045ad1f44b885dd8 (diff) | |
cgroup: fix lockdep warning in debug controller
The debug controller grabs cgroup_mutex from interface file show
functions which can deadlock and triggers lockdep warnings. Fix it by
using cgroup_kn_lock_live()/cgroup_kn_unlock() instead.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Diffstat (limited to 'kernel/cgroup')
| -rw-r--r-- | kernel/cgroup/debug.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/kernel/cgroup/debug.c b/kernel/cgroup/debug.c index 163fdbd7adf6..dac46af22782 100644 --- a/kernel/cgroup/debug.c +++ b/kernel/cgroup/debug.c | |||
| @@ -38,12 +38,15 @@ static u64 debug_taskcount_read(struct cgroup_subsys_state *css, | |||
| 38 | 38 | ||
| 39 | static int current_css_set_read(struct seq_file *seq, void *v) | 39 | static int current_css_set_read(struct seq_file *seq, void *v) |
| 40 | { | 40 | { |
| 41 | struct kernfs_open_file *of = seq->private; | ||
| 41 | struct css_set *cset; | 42 | struct css_set *cset; |
| 42 | struct cgroup_subsys *ss; | 43 | struct cgroup_subsys *ss; |
| 43 | struct cgroup_subsys_state *css; | 44 | struct cgroup_subsys_state *css; |
| 44 | int i, refcnt; | 45 | int i, refcnt; |
| 45 | 46 | ||
| 46 | mutex_lock(&cgroup_mutex); | 47 | if (!cgroup_kn_lock_live(of->kn, false)) |
| 48 | return -ENODEV; | ||
| 49 | |||
| 47 | spin_lock_irq(&css_set_lock); | 50 | spin_lock_irq(&css_set_lock); |
| 48 | rcu_read_lock(); | 51 | rcu_read_lock(); |
| 49 | cset = rcu_dereference(current->cgroups); | 52 | cset = rcu_dereference(current->cgroups); |
| @@ -65,7 +68,7 @@ static int current_css_set_read(struct seq_file *seq, void *v) | |||
| 65 | } | 68 | } |
| 66 | rcu_read_unlock(); | 69 | rcu_read_unlock(); |
| 67 | spin_unlock_irq(&css_set_lock); | 70 | spin_unlock_irq(&css_set_lock); |
| 68 | mutex_unlock(&cgroup_mutex); | 71 | cgroup_kn_unlock(of->kn); |
| 69 | return 0; | 72 | return 0; |
| 70 | } | 73 | } |
| 71 | 74 | ||
| @@ -174,13 +177,17 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) | |||
| 174 | 177 | ||
| 175 | static int cgroup_subsys_states_read(struct seq_file *seq, void *v) | 178 | static int cgroup_subsys_states_read(struct seq_file *seq, void *v) |
| 176 | { | 179 | { |
| 177 | struct cgroup *cgrp = seq_css(seq)->cgroup; | 180 | struct kernfs_open_file *of = seq->private; |
| 181 | struct cgroup *cgrp; | ||
| 178 | struct cgroup_subsys *ss; | 182 | struct cgroup_subsys *ss; |
| 179 | struct cgroup_subsys_state *css; | 183 | struct cgroup_subsys_state *css; |
| 180 | char pbuf[16]; | 184 | char pbuf[16]; |
| 181 | int i; | 185 | int i; |
| 182 | 186 | ||
| 183 | mutex_lock(&cgroup_mutex); | 187 | cgrp = cgroup_kn_lock_live(of->kn, false); |
| 188 | if (!cgrp) | ||
| 189 | return -ENODEV; | ||
| 190 | |||
| 184 | for_each_subsys(ss, i) { | 191 | for_each_subsys(ss, i) { |
| 185 | css = rcu_dereference_check(cgrp->subsys[ss->id], true); | 192 | css = rcu_dereference_check(cgrp->subsys[ss->id], true); |
| 186 | if (!css) | 193 | if (!css) |
| @@ -196,7 +203,8 @@ static int cgroup_subsys_states_read(struct seq_file *seq, void *v) | |||
| 196 | (unsigned long)css, css->id, | 203 | (unsigned long)css, css->id, |
| 197 | atomic_read(&css->online_cnt), pbuf); | 204 | atomic_read(&css->online_cnt), pbuf); |
| 198 | } | 205 | } |
| 199 | mutex_unlock(&cgroup_mutex); | 206 | |
| 207 | cgroup_kn_unlock(of->kn); | ||
| 200 | return 0; | 208 | return 0; |
| 201 | } | 209 | } |
| 202 | 210 | ||
| @@ -221,12 +229,17 @@ static void cgroup_masks_read_one(struct seq_file *seq, const char *name, | |||
| 221 | 229 | ||
| 222 | static int cgroup_masks_read(struct seq_file *seq, void *v) | 230 | static int cgroup_masks_read(struct seq_file *seq, void *v) |
| 223 | { | 231 | { |
| 224 | struct cgroup *cgrp = seq_css(seq)->cgroup; | 232 | struct kernfs_open_file *of = seq->private; |
| 233 | struct cgroup *cgrp; | ||
| 234 | |||
| 235 | cgrp = cgroup_kn_lock_live(of->kn, false); | ||
| 236 | if (!cgrp) | ||
| 237 | return -ENODEV; | ||
| 225 | 238 | ||
| 226 | mutex_lock(&cgroup_mutex); | ||
| 227 | cgroup_masks_read_one(seq, "subtree_control", cgrp->subtree_control); | 239 | cgroup_masks_read_one(seq, "subtree_control", cgrp->subtree_control); |
| 228 | cgroup_masks_read_one(seq, "subtree_ss_mask", cgrp->subtree_ss_mask); | 240 | cgroup_masks_read_one(seq, "subtree_ss_mask", cgrp->subtree_ss_mask); |
| 229 | mutex_unlock(&cgroup_mutex); | 241 | |
| 242 | cgroup_kn_unlock(of->kn); | ||
| 230 | return 0; | 243 | return 0; |
| 231 | } | 244 | } |
| 232 | 245 | ||
