diff options
Diffstat (limited to 'kernel/cgroup.c')
| -rw-r--r-- | kernel/cgroup.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 0f3527d6184a..b303dfc7dce0 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -255,12 +255,17 @@ int cgroup_lock_is_held(void) | |||
| 255 | 255 | ||
| 256 | EXPORT_SYMBOL_GPL(cgroup_lock_is_held); | 256 | EXPORT_SYMBOL_GPL(cgroup_lock_is_held); |
| 257 | 257 | ||
| 258 | static int css_unbias_refcnt(int refcnt) | ||
| 259 | { | ||
| 260 | return refcnt >= 0 ? refcnt : refcnt - CSS_DEACT_BIAS; | ||
| 261 | } | ||
| 262 | |||
| 258 | /* the current nr of refs, always >= 0 whether @css is deactivated or not */ | 263 | /* the current nr of refs, always >= 0 whether @css is deactivated or not */ |
| 259 | static int css_refcnt(struct cgroup_subsys_state *css) | 264 | static int css_refcnt(struct cgroup_subsys_state *css) |
| 260 | { | 265 | { |
| 261 | int v = atomic_read(&css->refcnt); | 266 | int v = atomic_read(&css->refcnt); |
| 262 | 267 | ||
| 263 | return v >= 0 ? v : v - CSS_DEACT_BIAS; | 268 | return css_unbias_refcnt(v); |
| 264 | } | 269 | } |
| 265 | 270 | ||
| 266 | /* convenient tests for these bits */ | 271 | /* convenient tests for these bits */ |
| @@ -3878,8 +3883,12 @@ static void css_dput_fn(struct work_struct *work) | |||
| 3878 | { | 3883 | { |
| 3879 | struct cgroup_subsys_state *css = | 3884 | struct cgroup_subsys_state *css = |
| 3880 | container_of(work, struct cgroup_subsys_state, dput_work); | 3885 | container_of(work, struct cgroup_subsys_state, dput_work); |
| 3886 | struct dentry *dentry = css->cgroup->dentry; | ||
| 3887 | struct super_block *sb = dentry->d_sb; | ||
| 3881 | 3888 | ||
| 3882 | dput(css->cgroup->dentry); | 3889 | atomic_inc(&sb->s_active); |
| 3890 | dput(dentry); | ||
| 3891 | deactivate_super(sb); | ||
| 3883 | } | 3892 | } |
| 3884 | 3893 | ||
| 3885 | static void init_cgroup_css(struct cgroup_subsys_state *css, | 3894 | static void init_cgroup_css(struct cgroup_subsys_state *css, |
| @@ -4971,10 +4980,12 @@ EXPORT_SYMBOL_GPL(__css_tryget); | |||
| 4971 | void __css_put(struct cgroup_subsys_state *css) | 4980 | void __css_put(struct cgroup_subsys_state *css) |
| 4972 | { | 4981 | { |
| 4973 | struct cgroup *cgrp = css->cgroup; | 4982 | struct cgroup *cgrp = css->cgroup; |
| 4983 | int v; | ||
| 4974 | 4984 | ||
| 4975 | rcu_read_lock(); | 4985 | rcu_read_lock(); |
| 4976 | atomic_dec(&css->refcnt); | 4986 | v = css_unbias_refcnt(atomic_dec_return(&css->refcnt)); |
| 4977 | switch (css_refcnt(css)) { | 4987 | |
| 4988 | switch (v) { | ||
| 4978 | case 1: | 4989 | case 1: |
| 4979 | if (notify_on_release(cgrp)) { | 4990 | if (notify_on_release(cgrp)) { |
| 4980 | set_bit(CGRP_RELEASABLE, &cgrp->flags); | 4991 | set_bit(CGRP_RELEASABLE, &cgrp->flags); |
