aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-06-28 08:10:14 -0400
committerTejun Heo <tj@kernel.org>2014-06-28 08:10:14 -0400
commit9a1049da9bd2cd83fe11d46433e603c193aa9c71 (patch)
tree007d2843abf0f064c294659334e69e297ffc2b74 /kernel
parent7d742075120deb831c7b94c268ca20d409e91d60 (diff)
percpu-refcount: require percpu_ref to be exited explicitly
Currently, a percpu_ref undoes percpu_ref_init() automatically by freeing the allocated percpu area when the percpu_ref is killed. While seemingly convenient, this has the following niggles. * It's impossible to re-init a released reference counter without going through re-allocation. * In the similar vein, it's impossible to initialize a percpu_ref count with static percpu variables. * We need and have an explicit destructor anyway for failure paths - percpu_ref_cancel_init(). This patch removes the automatic percpu counter freeing in percpu_ref_kill_rcu() and repurposes percpu_ref_cancel_init() into a generic destructor now named percpu_ref_exit(). percpu_ref_destroy() is considered but it gets confusing with percpu_ref_kill() while "exit" clearly indicates that it's the counterpart of percpu_ref_init(). All percpu_ref_cancel_init() users are updated to invoke percpu_ref_exit() instead and explicit percpu_ref_exit() calls are added to the destruction path of all percpu_ref users. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Benjamin LaHaise <bcrl@kvack.org> Cc: Kent Overstreet <kmo@daterainc.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Benjamin LaHaise <bcrl@kvack.org> Cc: Nicholas A. Bellinger <nab@linux-iscsi.org> Cc: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7868fc3c0bc5..c06aa5e257a8 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1638,7 +1638,7 @@ destroy_root:
1638exit_root_id: 1638exit_root_id:
1639 cgroup_exit_root_id(root); 1639 cgroup_exit_root_id(root);
1640cancel_ref: 1640cancel_ref:
1641 percpu_ref_cancel_init(&root_cgrp->self.refcnt); 1641 percpu_ref_exit(&root_cgrp->self.refcnt);
1642out: 1642out:
1643 free_cgrp_cset_links(&tmp_links); 1643 free_cgrp_cset_links(&tmp_links);
1644 return ret; 1644 return ret;
@@ -4133,6 +4133,8 @@ static void css_free_work_fn(struct work_struct *work)
4133 container_of(work, struct cgroup_subsys_state, destroy_work); 4133 container_of(work, struct cgroup_subsys_state, destroy_work);
4134 struct cgroup *cgrp = css->cgroup; 4134 struct cgroup *cgrp = css->cgroup;
4135 4135
4136 percpu_ref_exit(&css->refcnt);
4137
4136 if (css->ss) { 4138 if (css->ss) {
4137 /* css free path */ 4139 /* css free path */
4138 if (css->parent) 4140 if (css->parent)
@@ -4330,7 +4332,7 @@ err_list_del:
4330err_free_id: 4332err_free_id:
4331 cgroup_idr_remove(&ss->css_idr, css->id); 4333 cgroup_idr_remove(&ss->css_idr, css->id);
4332err_free_percpu_ref: 4334err_free_percpu_ref:
4333 percpu_ref_cancel_init(&css->refcnt); 4335 percpu_ref_exit(&css->refcnt);
4334err_free_css: 4336err_free_css:
4335 call_rcu(&css->rcu_head, css_free_rcu_fn); 4337 call_rcu(&css->rcu_head, css_free_rcu_fn);
4336 return err; 4338 return err;
@@ -4441,7 +4443,7 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
4441out_free_id: 4443out_free_id:
4442 cgroup_idr_remove(&root->cgroup_idr, cgrp->id); 4444 cgroup_idr_remove(&root->cgroup_idr, cgrp->id);
4443out_cancel_ref: 4445out_cancel_ref:
4444 percpu_ref_cancel_init(&cgrp->self.refcnt); 4446 percpu_ref_exit(&cgrp->self.refcnt);
4445out_free_cgrp: 4447out_free_cgrp:
4446 kfree(cgrp); 4448 kfree(cgrp);
4447out_unlock: 4449out_unlock: