diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ba7b3284c2e4..918658497625 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -5379,14 +5379,34 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, | |||
5379 | seq_printf(m, "%sname=%s", count ? "," : "", | 5379 | seq_printf(m, "%sname=%s", count ? "," : "", |
5380 | root->name); | 5380 | root->name); |
5381 | seq_putc(m, ':'); | 5381 | seq_putc(m, ':'); |
5382 | |||
5382 | cgrp = task_cgroup_from_root(tsk, root); | 5383 | cgrp = task_cgroup_from_root(tsk, root); |
5383 | path = cgroup_path(cgrp, buf, PATH_MAX); | 5384 | |
5384 | if (!path) { | 5385 | /* |
5385 | retval = -ENAMETOOLONG; | 5386 | * On traditional hierarchies, all zombie tasks show up as |
5386 | goto out_unlock; | 5387 | * belonging to the root cgroup. On the default hierarchy, |
5388 | * while a zombie doesn't show up in "cgroup.procs" and | ||
5389 | * thus can't be migrated, its /proc/PID/cgroup keeps | ||
5390 | * reporting the cgroup it belonged to before exiting. If | ||
5391 | * the cgroup is removed before the zombie is reaped, | ||
5392 | * " (deleted)" is appended to the cgroup path. | ||
5393 | */ | ||
5394 | if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) { | ||
5395 | path = cgroup_path(cgrp, buf, PATH_MAX); | ||
5396 | if (!path) { | ||
5397 | retval = -ENAMETOOLONG; | ||
5398 | goto out_unlock; | ||
5399 | } | ||
5400 | } else { | ||
5401 | path = "/"; | ||
5387 | } | 5402 | } |
5403 | |||
5388 | seq_puts(m, path); | 5404 | seq_puts(m, path); |
5389 | seq_putc(m, '\n'); | 5405 | |
5406 | if (cgroup_on_dfl(cgrp) && cgroup_is_dead(cgrp)) | ||
5407 | seq_puts(m, " (deleted)\n"); | ||
5408 | else | ||
5409 | seq_putc(m, '\n'); | ||
5390 | } | 5410 | } |
5391 | 5411 | ||
5392 | retval = 0; | 5412 | retval = 0; |
@@ -5593,7 +5613,6 @@ void cgroup_exit(struct task_struct *tsk) | |||
5593 | { | 5613 | { |
5594 | struct cgroup_subsys *ss; | 5614 | struct cgroup_subsys *ss; |
5595 | struct css_set *cset; | 5615 | struct css_set *cset; |
5596 | bool put_cset = false; | ||
5597 | int i; | 5616 | int i; |
5598 | 5617 | ||
5599 | /* | 5618 | /* |
@@ -5606,22 +5625,20 @@ void cgroup_exit(struct task_struct *tsk) | |||
5606 | spin_lock_bh(&css_set_lock); | 5625 | spin_lock_bh(&css_set_lock); |
5607 | css_set_move_task(tsk, cset, NULL, false); | 5626 | css_set_move_task(tsk, cset, NULL, false); |
5608 | spin_unlock_bh(&css_set_lock); | 5627 | spin_unlock_bh(&css_set_lock); |
5609 | put_cset = true; | 5628 | } else { |
5629 | get_css_set(cset); | ||
5610 | } | 5630 | } |
5611 | 5631 | ||
5612 | /* Reassign the task to the init_css_set. */ | ||
5613 | RCU_INIT_POINTER(tsk->cgroups, &init_css_set); | ||
5614 | |||
5615 | /* see cgroup_post_fork() for details */ | 5632 | /* see cgroup_post_fork() for details */ |
5616 | for_each_subsys_which(ss, i, &have_exit_callback) { | 5633 | for_each_subsys_which(ss, i, &have_exit_callback) |
5617 | struct cgroup_subsys_state *old_css = cset->subsys[i]; | 5634 | ss->exit(tsk); |
5618 | struct cgroup_subsys_state *css = task_css(tsk, i); | 5635 | } |
5619 | 5636 | ||
5620 | ss->exit(css, old_css, tsk); | 5637 | void cgroup_free(struct task_struct *task) |
5621 | } | 5638 | { |
5639 | struct css_set *cset = task_css_set(task); | ||
5622 | 5640 | ||
5623 | if (put_cset) | 5641 | put_css_set(cset); |
5624 | put_css_set(cset); | ||
5625 | } | 5642 | } |
5626 | 5643 | ||
5627 | static void check_for_release(struct cgroup *cgrp) | 5644 | static void check_for_release(struct cgroup *cgrp) |