aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup-defs.h2
-rw-r--r--kernel/cgroup/cgroup.c21
2 files changed, 8 insertions, 15 deletions
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 9f242b876fde..92d7640632ef 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -151,8 +151,8 @@ struct cgroup_subsys_state {
151 atomic_t online_cnt; 151 atomic_t online_cnt;
152 152
153 /* percpu_ref killing and RCU release */ 153 /* percpu_ref killing and RCU release */
154 struct rcu_head rcu_head;
155 struct work_struct destroy_work; 154 struct work_struct destroy_work;
155 struct rcu_work destroy_rwork;
156 156
157 /* 157 /*
158 * PI: the parent css. Placed here for cache proximity to following 158 * PI: the parent css. Placed here for cache proximity to following
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 8cda3bc3ae22..4c5d4ca0d4e4 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -4514,10 +4514,10 @@ static struct cftype cgroup_base_files[] = {
4514 * and thus involve punting to css->destroy_work adding two additional 4514 * and thus involve punting to css->destroy_work adding two additional
4515 * steps to the already complex sequence. 4515 * steps to the already complex sequence.
4516 */ 4516 */
4517static void css_free_work_fn(struct work_struct *work) 4517static void css_free_rwork_fn(struct work_struct *work)
4518{ 4518{
4519 struct cgroup_subsys_state *css = 4519 struct cgroup_subsys_state *css = container_of(to_rcu_work(work),
4520 container_of(work, struct cgroup_subsys_state, destroy_work); 4520 struct cgroup_subsys_state, destroy_rwork);
4521 struct cgroup_subsys *ss = css->ss; 4521 struct cgroup_subsys *ss = css->ss;
4522 struct cgroup *cgrp = css->cgroup; 4522 struct cgroup *cgrp = css->cgroup;
4523 4523
@@ -4563,15 +4563,6 @@ static void css_free_work_fn(struct work_struct *work)
4563 } 4563 }
4564} 4564}
4565 4565
4566static void css_free_rcu_fn(struct rcu_head *rcu_head)
4567{
4568 struct cgroup_subsys_state *css =
4569 container_of(rcu_head, struct cgroup_subsys_state, rcu_head);
4570
4571 INIT_WORK(&css->destroy_work, css_free_work_fn);
4572 queue_work(cgroup_destroy_wq, &css->destroy_work);
4573}
4574
4575static void css_release_work_fn(struct work_struct *work) 4566static void css_release_work_fn(struct work_struct *work)
4576{ 4567{
4577 struct cgroup_subsys_state *css = 4568 struct cgroup_subsys_state *css =
@@ -4621,7 +4612,8 @@ static void css_release_work_fn(struct work_struct *work)
4621 4612
4622 mutex_unlock(&cgroup_mutex); 4613 mutex_unlock(&cgroup_mutex);
4623 4614
4624 call_rcu(&css->rcu_head, css_free_rcu_fn); 4615 INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
4616 queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
4625} 4617}
4626 4618
4627static void css_release(struct percpu_ref *ref) 4619static void css_release(struct percpu_ref *ref)
@@ -4755,7 +4747,8 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
4755err_list_del: 4747err_list_del:
4756 list_del_rcu(&css->sibling); 4748 list_del_rcu(&css->sibling);
4757err_free_css: 4749err_free_css:
4758 call_rcu(&css->rcu_head, css_free_rcu_fn); 4750 INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
4751 queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
4759 return ERR_PTR(err); 4752 return ERR_PTR(err);
4760} 4753}
4761 4754