diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 62 |
1 files changed, 6 insertions, 56 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e9aa2a51ca68..4a94b0be598d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -178,7 +178,6 @@ static struct cftype cgroup_base_files[]; | |||
178 | static void cgroup_put(struct cgroup *cgrp); | 178 | static void cgroup_put(struct cgroup *cgrp); |
179 | static int rebind_subsystems(struct cgroup_root *dst_root, | 179 | static int rebind_subsystems(struct cgroup_root *dst_root, |
180 | unsigned int ss_mask); | 180 | unsigned int ss_mask); |
181 | static void cgroup_destroy_css_killed(struct cgroup *cgrp); | ||
182 | static int cgroup_destroy_locked(struct cgroup *cgrp); | 181 | static int cgroup_destroy_locked(struct cgroup *cgrp); |
183 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss); | 182 | static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss); |
184 | static void kill_css(struct cgroup_subsys_state *css); | 183 | static void kill_css(struct cgroup_subsys_state *css); |
@@ -4169,7 +4168,6 @@ static int online_css(struct cgroup_subsys_state *css) | |||
4169 | ret = ss->css_online(css); | 4168 | ret = ss->css_online(css); |
4170 | if (!ret) { | 4169 | if (!ret) { |
4171 | css->flags |= CSS_ONLINE; | 4170 | css->flags |= CSS_ONLINE; |
4172 | css->cgroup->nr_css++; | ||
4173 | rcu_assign_pointer(css->cgroup->subsys[ss->id], css); | 4171 | rcu_assign_pointer(css->cgroup->subsys[ss->id], css); |
4174 | } | 4172 | } |
4175 | return ret; | 4173 | return ret; |
@@ -4189,7 +4187,6 @@ static void offline_css(struct cgroup_subsys_state *css) | |||
4189 | ss->css_offline(css); | 4187 | ss->css_offline(css); |
4190 | 4188 | ||
4191 | css->flags &= ~CSS_ONLINE; | 4189 | css->flags &= ~CSS_ONLINE; |
4192 | css->cgroup->nr_css--; | ||
4193 | RCU_INIT_POINTER(css->cgroup->subsys[ss->id], NULL); | 4190 | RCU_INIT_POINTER(css->cgroup->subsys[ss->id], NULL); |
4194 | 4191 | ||
4195 | wake_up_all(&css->cgroup->offline_waitq); | 4192 | wake_up_all(&css->cgroup->offline_waitq); |
@@ -4374,39 +4371,18 @@ out_destroy: | |||
4374 | 4371 | ||
4375 | /* | 4372 | /* |
4376 | * This is called when the refcnt of a css is confirmed to be killed. | 4373 | * This is called when the refcnt of a css is confirmed to be killed. |
4377 | * css_tryget_online() is now guaranteed to fail. | 4374 | * css_tryget_online() is now guaranteed to fail. Tell the subsystem to |
4375 | * initate destruction and put the css ref from kill_css(). | ||
4378 | */ | 4376 | */ |
4379 | static void css_killed_work_fn(struct work_struct *work) | 4377 | static void css_killed_work_fn(struct work_struct *work) |
4380 | { | 4378 | { |
4381 | struct cgroup_subsys_state *css = | 4379 | struct cgroup_subsys_state *css = |
4382 | container_of(work, struct cgroup_subsys_state, destroy_work); | 4380 | container_of(work, struct cgroup_subsys_state, destroy_work); |
4383 | struct cgroup *cgrp = css->cgroup; | ||
4384 | 4381 | ||
4385 | mutex_lock(&cgroup_mutex); | 4382 | mutex_lock(&cgroup_mutex); |
4386 | |||
4387 | /* | ||
4388 | * css_tryget_online() is guaranteed to fail now. Tell subsystems | ||
4389 | * to initate destruction. | ||
4390 | */ | ||
4391 | offline_css(css); | 4383 | offline_css(css); |
4392 | |||
4393 | /* | ||
4394 | * If @cgrp is marked dead, it's waiting for refs of all css's to | ||
4395 | * be disabled before proceeding to the second phase of cgroup | ||
4396 | * destruction. If we are the last one, kick it off. | ||
4397 | */ | ||
4398 | if (!cgrp->nr_css && cgroup_is_dead(cgrp)) | ||
4399 | cgroup_destroy_css_killed(cgrp); | ||
4400 | |||
4401 | mutex_unlock(&cgroup_mutex); | 4384 | mutex_unlock(&cgroup_mutex); |
4402 | 4385 | ||
4403 | /* | ||
4404 | * Put the css refs from kill_css(). Each css holds an extra | ||
4405 | * reference to the cgroup's dentry and cgroup removal proceeds | ||
4406 | * regardless of css refs. On the last put of each css, whenever | ||
4407 | * that may be, the extra dentry ref is put so that dentry | ||
4408 | * destruction happens only after all css's are released. | ||
4409 | */ | ||
4410 | css_put(css); | 4386 | css_put(css); |
4411 | } | 4387 | } |
4412 | 4388 | ||
@@ -4518,11 +4494,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4518 | */ | 4494 | */ |
4519 | set_bit(CGRP_DEAD, &cgrp->flags); | 4495 | set_bit(CGRP_DEAD, &cgrp->flags); |
4520 | 4496 | ||
4521 | /* | 4497 | /* initiate massacre of all css's */ |
4522 | * Initiate massacre of all css's. cgroup_destroy_css_killed() | ||
4523 | * will be invoked to perform the rest of destruction once the | ||
4524 | * percpu refs of all css's are confirmed to be killed. | ||
4525 | */ | ||
4526 | for_each_css(css, ssid, cgrp) | 4498 | for_each_css(css, ssid, cgrp) |
4527 | kill_css(css); | 4499 | kill_css(css); |
4528 | 4500 | ||
@@ -4533,15 +4505,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4533 | raw_spin_unlock(&release_list_lock); | 4505 | raw_spin_unlock(&release_list_lock); |
4534 | 4506 | ||
4535 | /* | 4507 | /* |
4536 | * If @cgrp has css's attached, the second stage of cgroup | ||
4537 | * destruction is kicked off from css_killed_work_fn() after the | ||
4538 | * refs of all attached css's are killed. If @cgrp doesn't have | ||
4539 | * any css, we kick it off here. | ||
4540 | */ | ||
4541 | if (!cgrp->nr_css) | ||
4542 | cgroup_destroy_css_killed(cgrp); | ||
4543 | |||
4544 | /* | ||
4545 | * Remove @cgrp directory along with the base files. @cgrp has an | 4508 | * Remove @cgrp directory along with the base files. @cgrp has an |
4546 | * extra ref on its kn. | 4509 | * extra ref on its kn. |
4547 | */ | 4510 | */ |
@@ -4550,25 +4513,12 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4550 | set_bit(CGRP_RELEASABLE, &cgrp->parent->flags); | 4513 | set_bit(CGRP_RELEASABLE, &cgrp->parent->flags); |
4551 | check_for_release(cgrp->parent); | 4514 | check_for_release(cgrp->parent); |
4552 | 4515 | ||
4516 | /* put the base reference */ | ||
4517 | cgroup_put(cgrp); | ||
4518 | |||
4553 | return 0; | 4519 | return 0; |
4554 | }; | 4520 | }; |
4555 | 4521 | ||
4556 | /** | ||
4557 | * cgroup_destroy_css_killed - the second step of cgroup destruction | ||
4558 | * @cgrp: the cgroup whose csses have just finished offlining | ||
4559 | * | ||
4560 | * This function is invoked from a work item for a cgroup which is being | ||
4561 | * destroyed after all css's are offlined and performs the rest of | ||
4562 | * destruction. This is the second step of destruction described in the | ||
4563 | * comment above cgroup_destroy_locked(). | ||
4564 | */ | ||
4565 | static void cgroup_destroy_css_killed(struct cgroup *cgrp) | ||
4566 | { | ||
4567 | lockdep_assert_held(&cgroup_mutex); | ||
4568 | |||
4569 | cgroup_put(cgrp); | ||
4570 | } | ||
4571 | |||
4572 | static int cgroup_rmdir(struct kernfs_node *kn) | 4522 | static int cgroup_rmdir(struct kernfs_node *kn) |
4573 | { | 4523 | { |
4574 | struct cgroup *cgrp; | 4524 | struct cgroup *cgrp; |