Cgroup-v2 implementation of freezer ignores kernel threads, but still counts them against nr_frozen_tasks. So the cgroup with kthread inside will never report frozen.
In VZ containers we have "umh" and "kthreadd" kthreads in each container and we put them into container cgroups so that they share container resource limits. So container cgroups are virtually unfreezable. To make container cgroups freezable, let's count the number of kthreads in each cgroup, and offset nr_frozen_tasks checks with it. This way we can ignore kthreads completely and report cgroup frozen when all non-kthread tasks are frozen. Note: nr_kthreads is protected with css_set_lock. https://virtuozzo.atlassian.net/browse/VSTOR-118578 Signed-off-by: Pavel Tikhomirov <[email protected]> Feature: cgroup/freeze: improvements --- include/linux/cgroup-defs.h | 5 +++++ kernel/cgroup/cgroup.c | 23 +++++++++++++++++++++++ kernel/cgroup/freezer.c | 3 ++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 99979c8a06cfe..d68fca31e6e65 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -419,6 +419,11 @@ struct cgroup_freezer_state { * frozen, SIGSTOPped, and PTRACEd. */ int nr_frozen_tasks; + + /* + * Number of kernel threads in this cgroup + */ + int nr_kthreads; }; struct cgroup { diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 8e22aea876505..2f7db20f8a460 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -889,6 +889,23 @@ static void css_set_skip_task_iters(struct css_set *cset, css_task_iter_skip(it, task); } +/* + * Increment cgroup's nr_kthreads. + */ +static inline void cgroup_inc_kthread_cnt(struct cgroup *cgrp) +{ + cgrp->freezer.nr_kthreads++; +} + +/* + * Decrement cgroup's nr_kthreads. + */ +static inline void cgroup_dec_kthread_cnt(struct cgroup *cgrp) +{ + cgrp->freezer.nr_kthreads--; + WARN_ON_ONCE(cgrp->freezer.nr_kthreads < 0); +} + /** * css_set_move_task - move a task from one css_set to another * @task: task being moved @@ -935,7 +952,13 @@ static void css_set_move_task(struct task_struct *task, cgroup_move_task(task, to_cset); list_add_tail(&task->cg_list, use_mg_tasks ? &to_cset->mg_tasks : &to_cset->tasks); + + if (task->flags & PF_KTHREAD) + cgroup_inc_kthread_cnt(to_cset->dfl_cgrp); } + + if (from_cset && (task->flags & PF_KTHREAD)) + cgroup_dec_kthread_cnt(from_cset->dfl_cgrp); } /* diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c index 617861a547935..a2d9e55257bcc 100644 --- a/kernel/cgroup/freezer.c +++ b/kernel/cgroup/freezer.c @@ -61,7 +61,8 @@ void cgroup_update_frozen(struct cgroup *cgrp) * the cgroup frozen. Otherwise it's not frozen. */ frozen = test_bit(CGRP_FREEZE, &cgrp->flags) && - cgrp->freezer.nr_frozen_tasks == __cgroup_task_count(cgrp); + cgrp->freezer.nr_frozen_tasks + cgrp->freezer.nr_kthreads == + __cgroup_task_count(cgrp); if (frozen) { /* Already there? */ -- 2.51.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
