History

Merge branch 'for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup updates from Tejun Heo: - cgroup.kill is added which implements atomic killing of the whole subtree. Down the line, this should be able to replace the multiple userland implementations of "keep killing till empty". - PSI can now be turned off at boot time to avoid overhead for configurations which don't care about PSI. * 'for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: make per-cgroup pressure stall tracking configurable cgroup: Fix kernel-doc cgroup: inline cgroup_task_freeze() tests/cgroup: test cgroup.kill tests/cgroup: move cg_wait_for(), cg_prepare_for_wait() tests/cgroup: use cgroup.kill in cg_killall() docs/cgroup: add entry for cgroup.kill cgroup: introduce cgroup.kill

Linus Torvalds committed 5 years ago

Commit 3dbdb382 parents e267992 3958e2d13 files · +569 −108Browse files

Showing the changes to kernel (3 of 13 files). Show all

Unified · Split

3 files
  1. kernel/cgroup/cgroup.c +164 −16
  2. kernel/cgroup/rstat.c +1 −1
  3. kernel/sched/psi.c +17 −13
kernel/cgroup/cgroup.c+164−16
@@ -209,6 +209,22 @@ struct cgroup_namespace init_cgroup_ns = { · 208 unmodified lines
209static struct file_system_type cgroup2_fs_type;209static struct file_system_type cgroup2_fs_type;
210static struct cftype cgroup_base_files[];210static struct cftype cgroup_base_files[];
211 211
212/* cgroup optional features */
213enum cgroup_opt_features {
214#ifdef CONFIG_PSI
215 OPT_FEATURE_PRESSURE,
216#endif
217 OPT_FEATURE_COUNT
218};
219
220static const char *cgroup_opt_feature_names[OPT_FEATURE_COUNT] = {
221#ifdef CONFIG_PSI
222 "pressure",
223#endif
224};
225
226static u16 cgroup_feature_disable_mask __read_mostly;
227
212static int cgroup_apply_control(struct cgroup *cgrp);228static int cgroup_apply_control(struct cgroup *cgrp);
213static void cgroup_finalize_control(struct cgroup *cgrp, int ret);229static void cgroup_finalize_control(struct cgroup *cgrp, int ret);
214static void css_task_iter_skip(struct css_task_iter *it,230static void css_task_iter_skip(struct css_task_iter *it,
@@ -2390,7 +2406,7 @@ struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset, · 2175 unmodified lines
2390}2406}
2391 2407
2392/**2408/**
2393 * cgroup_taskset_migrate - migrate a taskset2409 * cgroup_migrate_execute - migrate a taskset
2394 * @mgctx: migration context2410 * @mgctx: migration context
2395 *2411 *
2396 * Migrate tasks in @mgctx as setup by migration preparation functions.2412 * Migrate tasks in @mgctx as setup by migration preparation functions.
@@ -3632,6 +3648,18 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) · 1235 unmodified lines
3632{3648{
3633 psi_trigger_replace(&of->priv, NULL);3649 psi_trigger_replace(&of->priv, NULL);
3634}3650}
3651
3652bool cgroup_psi_enabled(void)
3653{
3654 return (cgroup_feature_disable_mask & (1 << OPT_FEATURE_PRESSURE)) == 0;
3655}
3656
3657#else /* CONFIG_PSI */
3658bool cgroup_psi_enabled(void)
3659{
3660 return false;
3661}
3662
3635#endif /* CONFIG_PSI */3663#endif /* CONFIG_PSI */
3636 3664
3637static int cgroup_freeze_show(struct seq_file *seq, void *v)3665static int cgroup_freeze_show(struct seq_file *seq, void *v)
@@ -3668,6 +3696,80 @@ static ssize_t cgroup_freeze_write(struct kernfs_open_file *of, · 30 unmodified lines
3668 return nbytes;3696 return nbytes;
3669}3697}
3670 3698
3699static void __cgroup_kill(struct cgroup *cgrp)
3700{
3701 struct css_task_iter it;
3702 struct task_struct *task;
3703
3704 lockdep_assert_held(&cgroup_mutex);
3705
3706 spin_lock_irq(&css_set_lock);
3707 set_bit(CGRP_KILL, &cgrp->flags);
3708 spin_unlock_irq(&css_set_lock);
3709
3710 css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED, &it);
3711 while ((task = css_task_iter_next(&it))) {
3712 /* Ignore kernel threads here. */
3713 if (task->flags & PF_KTHREAD)
3714 continue;
3715
3716 /* Skip tasks that are already dying. */
3717 if (__fatal_signal_pending(task))
3718 continue;
3719
3720 send_sig(SIGKILL, task, 0);
3721 }
3722 css_task_iter_end(&it);
3723
3724 spin_lock_irq(&css_set_lock);
3725 clear_bit(CGRP_KILL, &cgrp->flags);
3726 spin_unlock_irq(&css_set_lock);
3727}
3728
3729static void cgroup_kill(struct cgroup *cgrp)
3730{
3731 struct cgroup_subsys_state *css;
3732 struct cgroup *dsct;
3733
3734 lockdep_assert_held(&cgroup_mutex);
3735
3736 cgroup_for_each_live_descendant_pre(dsct, css, cgrp)
3737 __cgroup_kill(dsct);
3738}
3739
3740static ssize_t cgroup_kill_write(struct kernfs_open_file *of, char *buf,
3741 size_t nbytes, loff_t off)
3742{
3743 ssize_t ret = 0;
3744 int kill;
3745 struct cgroup *cgrp;
3746
3747 ret = kstrtoint(strstrip(buf), 0, &kill);
3748 if (ret)
3749 return ret;
3750
3751 if (kill != 1)
3752 return -ERANGE;
3753
3754 cgrp = cgroup_kn_lock_live(of->kn, false);
3755 if (!cgrp)
3756 return -ENOENT;
3757
3758 /*
3759 * Killing is a process directed operation, i.e. the whole thread-group
3760 * is taken down so act like we do for cgroup.procs and only make this
3761 * writable in non-threaded cgroups.
3762 */
3763 if (cgroup_is_threaded(cgrp))
3764 ret = -EOPNOTSUPP;
3765 else
3766 cgroup_kill(cgrp);
3767
3768 cgroup_kn_unlock(of->kn);
3769
3770 return ret ?: nbytes;
3771}
3772
3671static int cgroup_file_open(struct kernfs_open_file *of)3773static int cgroup_file_open(struct kernfs_open_file *of)
3672{3774{
3673 struct cftype *cft = of_cft(of);3775 struct cftype *cft = of_cft(of);
@@ -3882,6 +3984,8 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, · 208 unmodified lines
3882restart:3984restart:
3883 for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {3985 for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {
3884 /* does cft->flags tell us to skip this file on @cgrp? */3986 /* does cft->flags tell us to skip this file on @cgrp? */
3987 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
3988 continue;
3885 if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))3989 if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))
3886 continue;3990 continue;
3887 if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp))3991 if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp))
@@ -3959,6 +4063,9 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) · 71 unmodified lines
3959 4063
3960 WARN_ON(cft->ss || cft->kf_ops);4064 WARN_ON(cft->ss || cft->kf_ops);
3961 4065
4066 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
4067 continue;
4068
3962 if (cft->seq_start)4069 if (cft->seq_start)
3963 kf_ops = &cgroup_kf_ops;4070 kf_ops = &cgroup_kf_ops;
3964 else4071 else
@@ -4860,6 +4967,11 @@ static struct cftype cgroup_base_files[] = { · 895 unmodified lines
4860 .seq_show = cgroup_freeze_show,4967 .seq_show = cgroup_freeze_show,
4861 .write = cgroup_freeze_write,4968 .write = cgroup_freeze_write,
4862 },4969 },
4970 {
4971 .name = "cgroup.kill",
4972 .flags = CFTYPE_NOT_ON_ROOT,
4973 .write = cgroup_kill_write,
4974 },
4863 {4975 {
4864 .name = "cpu.stat",4976 .name = "cpu.stat",
4865 .seq_show = cpu_stat_show,4977 .seq_show = cpu_stat_show,
@@ -4867,6 +4979,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
4867#ifdef CONFIG_PSI4979#ifdef CONFIG_PSI
4868 {4980 {
4869 .name = "io.pressure",4981 .name = "io.pressure",
4982 .flags = CFTYPE_PRESSURE,
4870 .seq_show = cgroup_io_pressure_show,4983 .seq_show = cgroup_io_pressure_show,
4871 .write = cgroup_io_pressure_write,4984 .write = cgroup_io_pressure_write,
4872 .poll = cgroup_pressure_poll,4985 .poll = cgroup_pressure_poll,
@@ -4874,6 +4987,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
4874 },4987 },
4875 {4988 {
4876 .name = "memory.pressure",4989 .name = "memory.pressure",
4990 .flags = CFTYPE_PRESSURE,
4877 .seq_show = cgroup_memory_pressure_show,4991 .seq_show = cgroup_memory_pressure_show,
4878 .write = cgroup_memory_pressure_write,4992 .write = cgroup_memory_pressure_write,
4879 .poll = cgroup_pressure_poll,4993 .poll = cgroup_pressure_poll,
@@ -4881,6 +4995,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
4881 },4995 },
4882 {4996 {
4883 .name = "cpu.pressure",4997 .name = "cpu.pressure",
4998 .flags = CFTYPE_PRESSURE,
4884 .seq_show = cgroup_cpu_pressure_show,4999 .seq_show = cgroup_cpu_pressure_show,
4885 .write = cgroup_cpu_pressure_write,5000 .write = cgroup_cpu_pressure_write,
4886 .poll = cgroup_pressure_poll,5001 .poll = cgroup_pressure_poll,
@@ -6080,6 +6195,8 @@ void cgroup_post_fork(struct task_struct *child, · 1193 unmodified lines
6080 struct kernel_clone_args *kargs)6195 struct kernel_clone_args *kargs)
6081 __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)6196 __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)
6082{6197{
6198 unsigned long cgrp_flags = 0;
6199 bool kill = false;
6083 struct cgroup_subsys *ss;6200 struct cgroup_subsys *ss;
6084 struct css_set *cset;6201 struct css_set *cset;
6085 int i;6202 int i;
@@ -6091,6 +6208,11 @@ void cgroup_post_fork(struct task_struct *child, · 5 unmodified lines
6091 6208
6092 /* init tasks are special, only link regular threads */6209 /* init tasks are special, only link regular threads */
6093 if (likely(child->pid)) {6210 if (likely(child->pid)) {
6211 if (kargs->cgrp)
6212 cgrp_flags = kargs->cgrp->flags;
6213 else
6214 cgrp_flags = cset->dfl_cgrp->flags;
6215
6094 WARN_ON_ONCE(!list_empty(&child->cg_list));6216 WARN_ON_ONCE(!list_empty(&child->cg_list));
6095 cset->nr_tasks++;6217 cset->nr_tasks++;
6096 css_set_move_task(child, NULL, cset, false);6218 css_set_move_task(child, NULL, cset, false);
@@ -6099,23 +6221,32 @@ void cgroup_post_fork(struct task_struct *child, · 2 unmodified lines
6099 cset = NULL;6221 cset = NULL;
6100 }6222 }
6101 6223
6102 /*6224 if (!(child->flags & PF_KTHREAD)) {
6103 * If the cgroup has to be frozen, the new task has too. Let's set6225 if (unlikely(test_bit(CGRP_FREEZE, &cgrp_flags))) {
6104 * the JOBCTL_TRAP_FREEZE jobctl bit to get the task into the6226 /*
6105 * frozen state.6227 * If the cgroup has to be frozen, the new task has
6106 */6228 * too. Let's set the JOBCTL_TRAP_FREEZE jobctl bit to
6107 if (unlikely(cgroup_task_freeze(child))) {6229 * get the task into the frozen state.
6108 spin_lock(&child->sighand->siglock);6230 */
6109 WARN_ON_ONCE(child->frozen);6231 spin_lock(&child->sighand->siglock);
6110 child->jobctl |= JOBCTL_TRAP_FREEZE;6232 WARN_ON_ONCE(child->frozen);
6111 spin_unlock(&child->sighand->siglock);6233 child->jobctl |= JOBCTL_TRAP_FREEZE;
6234 spin_unlock(&child->sighand->siglock);
6235
6236 /*
6237 * Calling cgroup_update_frozen() isn't required here,
6238 * because it will be called anyway a bit later from
6239 * do_freezer_trap(). So we avoid cgroup's transient
6240 * switch from the frozen state and back.
6241 */
6242 }
6112 6243
6113 /*6244 /*
6114 * Calling cgroup_update_frozen() isn't required here,6245 * If the cgroup is to be killed notice it now and take the
6115 * because it will be called anyway a bit later from6246 * child down right after we finished preparing it for
6116 * do_freezer_trap(). So we avoid cgroup's transient switch6247 * userspace.
6117 * from the frozen state and back.
6118 */6248 */
6249 kill = test_bit(CGRP_KILL, &cgrp_flags);
6119 }6250 }
6120 6251
6121 spin_unlock_irq(&css_set_lock);6252 spin_unlock_irq(&css_set_lock);
@@ -6138,6 +6269,10 @@ void cgroup_post_fork(struct task_struct *child, · 16 unmodified lines
6138 put_css_set(rcset);6269 put_css_set(rcset);
6139 }6270 }
6140 6271
6272 /* Cgroup has to be killed so take down child immediately. */
6273 if (unlikely(kill))
6274 do_send_sig_info(SIGKILL, SEND_SIG_NOINFO, child, PIDTYPE_TGID);
6275
6141 cgroup_css_set_put_fork(kargs);6276 cgroup_css_set_put_fork(kargs);
6142}6277}
6143 6278
@@ -6163,7 +6298,8 @@ void cgroup_exit(struct task_struct *tsk) · 19 unmodified lines
6163 cset->nr_tasks--;6298 cset->nr_tasks--;
6164 6299
6165 WARN_ON_ONCE(cgroup_task_frozen(tsk));6300 WARN_ON_ONCE(cgroup_task_frozen(tsk));
6166 if (unlikely(cgroup_task_freeze(tsk)))6301 if (unlikely(!(tsk->flags & PF_KTHREAD) &&
6302 test_bit(CGRP_FREEZE, &task_dfl_cgroup(tsk)->flags)))
6167 cgroup_update_frozen(task_dfl_cgroup(tsk));6303 cgroup_update_frozen(task_dfl_cgroup(tsk));
6168 6304
6169 spin_unlock_irq(&css_set_lock);6305 spin_unlock_irq(&css_set_lock);
@@ -6214,6 +6350,15 @@ static int __init cgroup_disable(char *str) · 44 unmodified lines
6214 pr_info("Disabling %s control group subsystem\n",6350 pr_info("Disabling %s control group subsystem\n",
6215 ss->name);6351 ss->name);
6216 }6352 }
6353
6354 for (i = 0; i < OPT_FEATURE_COUNT; i++) {
6355 if (strcmp(token, cgroup_opt_feature_names[i]))
6356 continue;
6357 cgroup_feature_disable_mask |= 1 << i;
6358 pr_info("Disabling %s control group feature\n",
6359 cgroup_opt_feature_names[i]);
6360 break;
6361 }
6217 }6362 }
6218 return 1;6363 return 1;
6219}6364}
@@ -6512,6 +6657,9 @@ static ssize_t show_delegatable_files(struct cftype *files, char *buf, · 292 unmodified lines
6512 if (!(cft->flags & CFTYPE_NS_DELEGATABLE))6657 if (!(cft->flags & CFTYPE_NS_DELEGATABLE))
6513 continue;6658 continue;
6514 6659
6660 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
6661 continue;
6662
6515 if (prefix)6663 if (prefix)
6516 ret += snprintf(buf + ret, size - ret, "%s.", prefix);6664 ret += snprintf(buf + ret, size - ret, "%s.", prefix);
6517 6665
kernel/cgroup/rstat.c+1−1
@@ -220,7 +220,7 @@ void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp) · 219 unmodified lines
220}220}
221 221
222/**222/**
223 * cgroup_rstat_flush_begin - flush stats in @cgrp's subtree and hold223 * cgroup_rstat_flush_hold - flush stats in @cgrp's subtree and hold
224 * @cgrp: target cgroup224 * @cgrp: target cgroup
225 *225 *
226 * Flush stats in @cgrp's subtree and prevent further flushes. Must be226 * Flush stats in @cgrp's subtree and prevent further flushes. Must be
kernel/sched/psi.c+17−13
@@ -148,6 +148,7 @@ · 147 unmodified lines
148static int psi_bug __read_mostly;148static int psi_bug __read_mostly;
149 149
150DEFINE_STATIC_KEY_FALSE(psi_disabled);150DEFINE_STATIC_KEY_FALSE(psi_disabled);
151DEFINE_STATIC_KEY_TRUE(psi_cgroups_enabled);
151 152
152#ifdef CONFIG_PSI_DEFAULT_DISABLED153#ifdef CONFIG_PSI_DEFAULT_DISABLED
153static bool psi_enable;154static bool psi_enable;
@@ -215,6 +216,9 @@ void __init psi_init(void) · 61 unmodified lines
215 return;216 return;
216 }217 }
217 218
219 if (!cgroup_psi_enabled())
220 static_branch_disable(&psi_cgroups_enabled);
221
218 psi_period = jiffies_to_nsecs(PSI_FREQ);222 psi_period = jiffies_to_nsecs(PSI_FREQ);
219 group_init(&psi_system);223 group_init(&psi_system);
220}224}
@@ -748,23 +752,23 @@ static void psi_group_change(struct psi_group *group, int cpu, · 527 unmodified lines
748 752
749static struct psi_group *iterate_groups(struct task_struct *task, void **iter)753static struct psi_group *iterate_groups(struct task_struct *task, void **iter)
750{754{
755 if (*iter == &psi_system)
756 return NULL;
757
751#ifdef CONFIG_CGROUPS758#ifdef CONFIG_CGROUPS
752 struct cgroup *cgroup = NULL;759 if (static_branch_likely(&psi_cgroups_enabled)) {
760 struct cgroup *cgroup = NULL;
753 761
754 if (!*iter)762 if (!*iter)
755 cgroup = task->cgroups->dfl_cgrp;763 cgroup = task->cgroups->dfl_cgrp;
756 else if (*iter == &psi_system)764 else
757 return NULL;765 cgroup = cgroup_parent(*iter);
758 else
759 cgroup = cgroup_parent(*iter);
760 766
761 if (cgroup && cgroup_parent(cgroup)) {767 if (cgroup && cgroup_parent(cgroup)) {
762 *iter = cgroup;768 *iter = cgroup;
763 return cgroup_psi(cgroup);769 return cgroup_psi(cgroup);
770 }
764 }771 }
765#else
766 if (*iter)
767 return NULL;
768#endif772#endif
769 *iter = &psi_system;773 *iter = &psi_system;
770 return &psi_system;774 return &psi_system;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t