diff options
| author | Roman Gushchin <guro@fb.com> | 2019-04-26 13:59:45 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2019-05-06 11:39:11 -0400 |
| commit | 96b9c592def5d7203bdad1337d9c92a2183de5cb (patch) | |
| tree | e7e9f4f31aa3c2182de25d660aba59cf3325d4cd | |
| parent | cb2c4cd87874a7975b7b8615866b3a87bae10aab (diff) | |
cgroup: get rid of cgroup_freezer_frozen_exit()
A task should never enter the exit path with the task->frozen bit set.
Any frozen task must enter the signal handling loop and the only
way to escape is through cgroup_leave_frozen(true), which
unconditionally drops the task->frozen bit. So it means that
cgroyp_freezer_frozen_exit() has zero chances to be called and
has to be removed.
Let's put a WARN_ON_ONCE() instead of the cgroup_freezer_frozen_exit()
call to catch any potential leak of the task's frozen bit.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Roman Gushchin <guro@fb.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
| -rw-r--r-- | include/linux/cgroup.h | 2 | ||||
| -rw-r--r-- | kernel/cgroup/cgroup.c | 5 | ||||
| -rw-r--r-- | kernel/cgroup/freezer.c | 10 |
3 files changed, 3 insertions, 14 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 3e2efd412dfa..c0077adeea83 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
| @@ -889,7 +889,7 @@ void cgroup_update_frozen(struct cgroup *cgrp); | |||
| 889 | void cgroup_freeze(struct cgroup *cgrp, bool freeze); | 889 | void cgroup_freeze(struct cgroup *cgrp, bool freeze); |
| 890 | void cgroup_freezer_migrate_task(struct task_struct *task, struct cgroup *src, | 890 | void cgroup_freezer_migrate_task(struct task_struct *task, struct cgroup *src, |
| 891 | struct cgroup *dst); | 891 | struct cgroup *dst); |
| 892 | void cgroup_freezer_frozen_exit(struct task_struct *task); | 892 | |
| 893 | static inline bool cgroup_task_freeze(struct task_struct *task) | 893 | static inline bool cgroup_task_freeze(struct task_struct *task) |
| 894 | { | 894 | { |
| 895 | bool ret; | 895 | bool ret; |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 4fe9f7f1a3fa..327f37c9fdfa 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
| @@ -5926,9 +5926,8 @@ void cgroup_exit(struct task_struct *tsk) | |||
| 5926 | css_set_move_task(tsk, cset, NULL, false); | 5926 | css_set_move_task(tsk, cset, NULL, false); |
| 5927 | cset->nr_tasks--; | 5927 | cset->nr_tasks--; |
| 5928 | 5928 | ||
| 5929 | if (unlikely(cgroup_task_frozen(tsk))) | 5929 | WARN_ON_ONCE(cgroup_task_frozen(tsk)); |
| 5930 | cgroup_freezer_frozen_exit(tsk); | 5930 | if (unlikely(cgroup_task_freeze(tsk))) |
| 5931 | else if (unlikely(cgroup_task_freeze(tsk))) | ||
| 5932 | cgroup_update_frozen(task_dfl_cgroup(tsk)); | 5931 | cgroup_update_frozen(task_dfl_cgroup(tsk)); |
| 5933 | 5932 | ||
| 5934 | spin_unlock_irq(&css_set_lock); | 5933 | spin_unlock_irq(&css_set_lock); |
diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c index c321e768f8d3..8cf010680678 100644 --- a/kernel/cgroup/freezer.c +++ b/kernel/cgroup/freezer.c | |||
| @@ -248,16 +248,6 @@ void cgroup_freezer_migrate_task(struct task_struct *task, | |||
| 248 | cgroup_freeze_task(task, test_bit(CGRP_FREEZE, &dst->flags)); | 248 | cgroup_freeze_task(task, test_bit(CGRP_FREEZE, &dst->flags)); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | void cgroup_freezer_frozen_exit(struct task_struct *task) | ||
| 252 | { | ||
| 253 | struct cgroup *cgrp = task_dfl_cgroup(task); | ||
| 254 | |||
| 255 | lockdep_assert_held(&css_set_lock); | ||
| 256 | |||
| 257 | cgroup_dec_frozen_cnt(cgrp); | ||
| 258 | cgroup_update_frozen(cgrp); | ||
| 259 | } | ||
| 260 | |||
| 261 | void cgroup_freeze(struct cgroup *cgrp, bool freeze) | 251 | void cgroup_freeze(struct cgroup *cgrp, bool freeze) |
| 262 | { | 252 | { |
| 263 | struct cgroup_subsys_state *css; | 253 | struct cgroup_subsys_state *css; |
