diff options
author | Colin Cross <ccross@android.com> | 2010-11-23 21:37:03 -0800 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-05-23 15:43:51 -0700 |
commit | 3bc0d49a499be73e94f53b50420d217565757e6d (patch) | |
tree | cffc1f0b02c934619d4bd56aab7968faffeec033 /kernel | |
parent | c2d599be4d62be057cbcaaf8b73c407a0fb29bc2 (diff) |
cgroup: Set CGRP_RELEASABLE when adding to a cgroup
Changes the meaning of CGRP_RELEASABLE to be set on any cgroup
that has ever had a task or cgroup in it, or had css_get called
on it. The bit is set in cgroup_attach_task, cgroup_create,
and __css_get. It is not necessary to set the bit in
cgroup_fork, as the task is either in the root cgroup, in
which can never be released, or the task it was forked from
already set the bit in croup_attach_task.
Signed-off-by: Colin Cross <ccross@android.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d1fe8b209943..307ff0134b7b 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -339,7 +339,15 @@ static void free_css_set_rcu(struct rcu_head *obj) * compiled into their kernel but not actually in use */ static int use_task_css_set_links __read_mostly; -static void __put_css_set(struct css_set *cg, int taskexit) +/* + * refcounted get/put for css_set objects + */ +static inline void get_css_set(struct css_set *cg) +{ + atomic_inc(&cg->refcount); +} + +static void put_css_set(struct css_set *cg) { struct cg_cgroup_link *link; struct cg_cgroup_link *saved_link; @@ -365,12 +373,8 @@ static void __put_css_set(struct css_set *cg, int taskexit) struct cgroup *cgrp = link->cgrp; list_del(&link->cg_link_list); list_del(&link->cgrp_link_list); - if (atomic_dec_and_test(&cgrp->count) && - notify_on_release(cgrp)) { - if (taskexit) - set_bit(CGRP_RELEASABLE, &cgrp->flags); + if (atomic_dec_and_test(&cgrp->count)) check_for_release(cgrp); - } kfree(link); } @@ -380,24 +384,6 @@ static void __put_css_set(struct css_set *cg, int taskexit) } /* - * refcounted get/put for css_set objects - */ -static inline void get_css_set(struct css_set *cg) -{ - atomic_inc(&cg->refcount); -} - -static inline void put_css_set(struct css_set *cg) -{ - __put_css_set(cg, 0); -} - -static inline void put_css_set_taskexit(struct css_set *cg) -{ - __put_css_set(cg, 1); -} - -/* * compare_css_sets - helper function for find_existing_css_set(). * @cg: candidate css_set being tested * @old_cg: existing css_set for a task @@ -1831,7 +1817,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) if (ss->attach) ss->attach(ss, cgrp, oldcgrp, tsk, false); } - set_bit(CGRP_RELEASABLE, &oldcgrp->flags); + set_bit(CGRP_RELEASABLE, &cgrp->flags); synchronize_rcu(); put_css_set(cg); @@ -3451,6 +3437,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, if (err < 0) goto err_remove; + set_bit(CGRP_RELEASABLE, &parent->flags); + /* The cgroup directory was pre-locked for us */ BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex)); @@ -3667,7 +3655,6 @@ again: cgroup_d_remove_dir(d); dput(d); - set_bit(CGRP_RELEASABLE, &parent->flags); check_for_release(parent); /* @@ -4267,7 +4254,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) task_unlock(tsk); if (cg) - put_css_set_taskexit(cg); + put_css_set(cg); } /** @@ -4437,6 +4424,14 @@ static void check_for_release(struct cgroup *cgrp) } /* Caller must verify that the css is not for root cgroup */ +void __css_get(struct cgroup_subsys_state *css, int count) +{ + atomic_add(count, &css->refcnt); + set_bit(CGRP_RELEASABLE, &css->cgroup->flags); +} +EXPORT_SYMBOL_GPL(__css_get); + +/* Caller must verify that the css is not for root cgroup */ void __css_put(struct cgroup_subsys_state *css, int count) { struct cgroup *cgrp = css->cgroup; @@ -4444,10 +4439,7 @@ void __css_put(struct cgroup_subsys_state *css, int count) rcu_read_lock(); val = atomic_sub_return(count, &css->refcnt); if (val == 1) { - if (notify_on_release(cgrp)) { - set_bit(CGRP_RELEASABLE, &cgrp->flags); - check_for_release(cgrp); - } + check_for_release(cgrp); cgroup_wakeup_rmdir_waiter(cgrp); } rcu_read_unlock(); |