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
209209 static struct file_system_type cgroup2_fs_type;
210210 static struct cftype cgroup_base_files[];
211211
212+/* cgroup optional features */
213+enum cgroup_opt_features {
214+#ifdef CONFIG_PSI
215+ OPT_FEATURE_PRESSURE,
216+#endif
217+ OPT_FEATURE_COUNT
218+};
219+
220+static const char *cgroup_opt_feature_names[OPT_FEATURE_COUNT] = {
221+#ifdef CONFIG_PSI
222+ "pressure",
223+#endif
224+};
225+
226+static u16 cgroup_feature_disable_mask __read_mostly;
227+
212228 static int cgroup_apply_control(struct cgroup *cgrp);
213229 static void cgroup_finalize_control(struct cgroup *cgrp, int ret);
214230 static 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
23902406 }
23912407
23922408 /**
2393− * cgroup_taskset_migrate - migrate a taskset
2409+ * cgroup_migrate_execute - migrate a taskset
23942410 * @mgctx: migration context
23952411 *
23962412 * 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
36323648 {
36333649 psi_trigger_replace(&of->priv, NULL);
36343650 }
3651+
3652+bool cgroup_psi_enabled(void)
3653+{
3654+ return (cgroup_feature_disable_mask & (1 << OPT_FEATURE_PRESSURE)) == 0;
3655+}
3656+
3657+#else /* CONFIG_PSI */
3658+bool cgroup_psi_enabled(void)
3659+{
3660+ return false;
3661+}
3662+
36353663 #endif /* CONFIG_PSI */
36363664
36373665 static 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
36683696 return nbytes;
36693697 }
36703698
3699+static 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+
3729+static 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+
3740+static 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+
36713773 static int cgroup_file_open(struct kernfs_open_file *of)
36723774 {
36733775 struct cftype *cft = of_cft(of);
@@ -3882,6 +3984,8 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, · 208 unmodified lines
38823984 restart:
38833985 for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {
38843986 /* does cft->flags tell us to skip this file on @cgrp? */
3987+ if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
3988+ continue;
38853989 if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))
38863990 continue;
38873991 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
39594063
39604064 WARN_ON(cft->ss || cft->kf_ops);
39614065
4066+ if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
4067+ continue;
4068+
39624069 if (cft->seq_start)
39634070 kf_ops = &cgroup_kf_ops;
39644071 else
@@ -4860,6 +4967,11 @@ static struct cftype cgroup_base_files[] = { · 895 unmodified lines
48604967 .seq_show = cgroup_freeze_show,
48614968 .write = cgroup_freeze_write,
48624969 },
4970+ {
4971+ .name = "cgroup.kill",
4972+ .flags = CFTYPE_NOT_ON_ROOT,
4973+ .write = cgroup_kill_write,
4974+ },
48634975 {
48644976 .name = "cpu.stat",
48654977 .seq_show = cpu_stat_show,
@@ -4867,6 +4979,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
48674979 #ifdef CONFIG_PSI
48684980 {
48694981 .name = "io.pressure",
4982+ .flags = CFTYPE_PRESSURE,
48704983 .seq_show = cgroup_io_pressure_show,
48714984 .write = cgroup_io_pressure_write,
48724985 .poll = cgroup_pressure_poll,
@@ -4874,6 +4987,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
48744987 },
48754988 {
48764989 .name = "memory.pressure",
4990+ .flags = CFTYPE_PRESSURE,
48774991 .seq_show = cgroup_memory_pressure_show,
48784992 .write = cgroup_memory_pressure_write,
48794993 .poll = cgroup_pressure_poll,
@@ -4881,6 +4995,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
48814995 },
48824996 {
48834997 .name = "cpu.pressure",
4998+ .flags = CFTYPE_PRESSURE,
48844999 .seq_show = cgroup_cpu_pressure_show,
48855000 .write = cgroup_cpu_pressure_write,
48865001 .poll = cgroup_pressure_poll,
@@ -6080,6 +6195,8 @@ void cgroup_post_fork(struct task_struct *child, · 1193 unmodified lines
60806195 struct kernel_clone_args *kargs)
60816196 __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)
60826197 {
6198+ unsigned long cgrp_flags = 0;
6199+ bool kill = false;
60836200 struct cgroup_subsys *ss;
60846201 struct css_set *cset;
60856202 int i;
@@ -6091,6 +6208,11 @@ void cgroup_post_fork(struct task_struct *child, · 5 unmodified lines
60916208
60926209 /* init tasks are special, only link regular threads */
60936210 if (likely(child->pid)) {
6211+ if (kargs->cgrp)
6212+ cgrp_flags = kargs->cgrp->flags;
6213+ else
6214+ cgrp_flags = cset->dfl_cgrp->flags;
6215+
60946216 WARN_ON_ONCE(!list_empty(&child->cg_list));
60956217 cset->nr_tasks++;
60966218 css_set_move_task(child, NULL, cset, false);
@@ -6099,23 +6221,32 @@ void cgroup_post_fork(struct task_struct *child, · 2 unmodified lines
60996221 cset = NULL;
61006222 }
61016223
6102− /*
6103− * If the cgroup has to be frozen, the new task has too. Let's set
6104− * the JOBCTL_TRAP_FREEZE jobctl bit to get the task into the
6105− * frozen state.
6106− */
6107− if (unlikely(cgroup_task_freeze(child))) {
6108− spin_lock(&child->sighand->siglock);
6109− WARN_ON_ONCE(child->frozen);
6110− child->jobctl |= JOBCTL_TRAP_FREEZE;
6111− spin_unlock(&child->sighand->siglock);
6224+ if (!(child->flags & PF_KTHREAD)) {
6225+ if (unlikely(test_bit(CGRP_FREEZE, &cgrp_flags))) {
6226+ /*
6227+ * If the cgroup has to be frozen, the new task has
6228+ * too. Let's set the JOBCTL_TRAP_FREEZE jobctl bit to
6229+ * get the task into the frozen state.
6230+ */
6231+ spin_lock(&child->sighand->siglock);
6232+ WARN_ON_ONCE(child->frozen);
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+ }
61126243
61136244 /*
6114− * Calling cgroup_update_frozen() isn't required here,
6115− * because it will be called anyway a bit later from
6116− * do_freezer_trap(). So we avoid cgroup's transient switch
6117− * from the frozen state and back.
6245+ * If the cgroup is to be killed notice it now and take the
6246+ * child down right after we finished preparing it for
6247+ * userspace.
61186248 */
6249+ kill = test_bit(CGRP_KILL, &cgrp_flags);
61196250 }
61206251
61216252 spin_unlock_irq(&css_set_lock);
@@ -6138,6 +6269,10 @@ void cgroup_post_fork(struct task_struct *child, · 16 unmodified lines
61386269 put_css_set(rcset);
61396270 }
61406271
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+
61416276 cgroup_css_set_put_fork(kargs);
61426277 }
61436278
@@ -6163,7 +6298,8 @@ void cgroup_exit(struct task_struct *tsk) · 19 unmodified lines
61636298 cset->nr_tasks--;
61646299
61656300 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)))
61676303 cgroup_update_frozen(task_dfl_cgroup(tsk));
61686304
61696305 spin_unlock_irq(&css_set_lock);
@@ -6214,6 +6350,15 @@ static int __init cgroup_disable(char *str) · 44 unmodified lines
62146350 pr_info("Disabling %s control group subsystem\n",
62156351 ss->name);
62166352 }
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+ }
62176362 }
62186363 return 1;
62196364 }
@@ -6512,6 +6657,9 @@ static ssize_t show_delegatable_files(struct cftype *files, char *buf, · 292 unmodified lines
65126657 if (!(cft->flags & CFTYPE_NS_DELEGATABLE))
65136658 continue;
65146659
6660+ if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
6661+ continue;
6662+
65156663 if (prefix)
65166664 ret += snprintf(buf + ret, size - ret, "%s.", prefix);
65176665
kernel/cgroup/rstat.c+1−1
@@ -220,7 +220,7 @@ void cgroup_rstat_flush_irqsafe(struct cgroup *cgrp) · 219 unmodified lines
220220 }
221221
222222 /**
223− * cgroup_rstat_flush_begin - flush stats in @cgrp's subtree and hold
223+ * cgroup_rstat_flush_hold - flush stats in @cgrp's subtree and hold
224224 * @cgrp: target cgroup
225225 *
226226 * 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
148148 static int psi_bug __read_mostly;
149149
150150 DEFINE_STATIC_KEY_FALSE(psi_disabled);
151+DEFINE_STATIC_KEY_TRUE(psi_cgroups_enabled);
151152
152153 #ifdef CONFIG_PSI_DEFAULT_DISABLED
153154 static bool psi_enable;
@@ -215,6 +216,9 @@ void __init psi_init(void) · 61 unmodified lines
215216 return;
216217 }
217218
219+ if (!cgroup_psi_enabled())
220+ static_branch_disable(&psi_cgroups_enabled);
221+
218222 psi_period = jiffies_to_nsecs(PSI_FREQ);
219223 group_init(&psi_system);
220224 }
@@ -748,23 +752,23 @@ static void psi_group_change(struct psi_group *group, int cpu, · 527 unmodified lines
748752
749753 static struct psi_group *iterate_groups(struct task_struct *task, void **iter)
750754 {
755+ if (*iter == &psi_system)
756+ return NULL;
757+
751758 #ifdef CONFIG_CGROUPS
752− struct cgroup *cgroup = NULL;
759+ if (static_branch_likely(&psi_cgroups_enabled)) {
760+ struct cgroup *cgroup = NULL;
753761
754− if (!*iter)
755− cgroup = task->cgroups->dfl_cgrp;
756− else if (*iter == &psi_system)
757− return NULL;
758− else
759− cgroup = cgroup_parent(*iter);
762+ if (!*iter)
763+ cgroup = task->cgroups->dfl_cgrp;
764+ else
765+ cgroup = cgroup_parent(*iter);
760766
761− if (cgroup && cgroup_parent(cgroup)) {
762− *iter = cgroup;
763− return cgroup_psi(cgroup);
767+ if (cgroup && cgroup_parent(cgroup)) {
768+ *iter = cgroup;
769+ return cgroup_psi(cgroup);
770+ }
764771 }
765−#else
766− if (*iter)
767− return NULL;
768772 #endif
769773 *iter = &psi_system;
770774 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