diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2009-10-01 18:44:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-01 19:11:12 -0400 |
commit | 3dece8347df6a16239fab10dadb370854f1c969c (patch) | |
tree | 23a93cdb0dfacd4b89b42c192a6247be84d105bf /kernel/cgroup.c | |
parent | 26251eaf98e26dc2ce2dc26d63bc502700760704 (diff) |
cgroup: catch bad css refcnt at css_put
__css_put() doesn't check a bug as refcnt goes to minus.
I think it should be caught. This patch adds a check for it.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Paul Menage <menage@google.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.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>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d2b88596efde..ca83b73fba19 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -3708,8 +3708,10 @@ static void check_for_release(struct cgroup *cgrp) | |||
3708 | void __css_put(struct cgroup_subsys_state *css) | 3708 | void __css_put(struct cgroup_subsys_state *css) |
3709 | { | 3709 | { |
3710 | struct cgroup *cgrp = css->cgroup; | 3710 | struct cgroup *cgrp = css->cgroup; |
3711 | int val; | ||
3711 | rcu_read_lock(); | 3712 | rcu_read_lock(); |
3712 | if (atomic_dec_return(&css->refcnt) == 1) { | 3713 | val = atomic_dec_return(&css->refcnt); |
3714 | if (val == 1) { | ||
3713 | if (notify_on_release(cgrp)) { | 3715 | if (notify_on_release(cgrp)) { |
3714 | set_bit(CGRP_RELEASABLE, &cgrp->flags); | 3716 | set_bit(CGRP_RELEASABLE, &cgrp->flags); |
3715 | check_for_release(cgrp); | 3717 | check_for_release(cgrp); |
@@ -3717,6 +3719,7 @@ void __css_put(struct cgroup_subsys_state *css) | |||
3717 | cgroup_wakeup_rmdir_waiter(cgrp); | 3719 | cgroup_wakeup_rmdir_waiter(cgrp); |
3718 | } | 3720 | } |
3719 | rcu_read_unlock(); | 3721 | rcu_read_unlock(); |
3722 | WARN_ON_ONCE(val < 1); | ||
3720 | } | 3723 | } |
3721 | 3724 | ||
3722 | /* | 3725 | /* |