aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2008-11-19 18:36:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-11-19 21:49:58 -0500
commit3fa59dfbc3b223f02c26593be69ce6fc9a940405 (patch)
treed3d9df521342b49abc636e1ee465b704858b3e0d
parent0ae15132a4f5c758a6ffcde74495641dc3f62ba1 (diff)
cgroup: fix potential deadlock in pre_destroy
As Balbir pointed out, memcg's pre_destroy handler has potential deadlock. It has following lock sequence. cgroup_mutex (cgroup_rmdir) -> pre_destroy -> mem_cgroup_pre_destroy-> force_empty -> cpu_hotplug.lock. (lru_add_drain_all-> schedule_work-> get_online_cpus) But, cpuset has following. cpu_hotplug.lock (call notifier) -> cgroup_mutex. (within notifier) Then, this lock sequence should be fixed. Considering how pre_destroy works, it's not necessary to holding cgroup_mutex() while calling it. As a side effect, we don't have to wait at this mutex while memcg's force_empty works.(it can be long when there are tons of pages.) Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Paul Menage <menage@google.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/cgroup.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 358e77564e6f..1a06be61dcd0 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2472,10 +2472,7 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
2472 mutex_unlock(&cgroup_mutex); 2472 mutex_unlock(&cgroup_mutex);
2473 return -EBUSY; 2473 return -EBUSY;
2474 } 2474 }
2475 2475 mutex_unlock(&cgroup_mutex);
2476 parent = cgrp->parent;
2477 root = cgrp->root;
2478 sb = root->sb;
2479 2476
2480 /* 2477 /*
2481 * Call pre_destroy handlers of subsys. Notify subsystems 2478 * Call pre_destroy handlers of subsys. Notify subsystems
@@ -2483,7 +2480,14 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
2483 */ 2480 */
2484 cgroup_call_pre_destroy(cgrp); 2481 cgroup_call_pre_destroy(cgrp);
2485 2482
2486 if (cgroup_has_css_refs(cgrp)) { 2483 mutex_lock(&cgroup_mutex);
2484 parent = cgrp->parent;
2485 root = cgrp->root;
2486 sb = root->sb;
2487
2488 if (atomic_read(&cgrp->count)
2489 || !list_empty(&cgrp->children)
2490 || cgroup_has_css_refs(cgrp)) {
2487 mutex_unlock(&cgroup_mutex); 2491 mutex_unlock(&cgroup_mutex);
2488 return -EBUSY; 2492 return -EBUSY;
2489 } 2493 }