History

cgroup: make per-cgroup pressure stall tracking configurable

PSI accounts stalls for each cgroup separately and aggregates it at each level of the hierarchy. This causes additional overhead with psi_avgs_work being called for each cgroup in the hierarchy. psi_avgs_work has been highly optimized, however on systems with large number of cgroups the overhead becomes noticeable. Systems which use PSI only at the system level could avoid this overhead if PSI can be configured to skip per-cgroup stall accounting. Add "cgroup_disable=pressure" kernel command-line option to allow requesting system-wide only pressure stall accounting. When set, it keeps system-wide accounting under /proc/pressure/ but skips accounting for individual cgroups and does not expose PSI nodes in cgroup hierarchy.

Suren Baghdasaryan committed 5 years ago

Commit 3958e2d1 parent 2ca11b05 files · +80 −15Browse files

Unified · Split

5 files
  1. Documentation/admin-guide/kernel-parameters.txt +7 −2
  2. include/linux/cgroup-defs.h +1 −0
  3. include/linux/cgroup.h +7 −0
  4. kernel/cgroup/cgroup.c +48 −0
  5. kernel/sched/psi.c +17 −13
Documentation/admin-guide/kernel-parameters.txt+7−2
@@ -497,16 +497,21 @@ · 496 unmodified lines
497 ccw_timeout_log [S390]497 ccw_timeout_log [S390]
498 See Documentation/s390/common_io.rst for details.498 See Documentation/s390/common_io.rst for details.
499 499
500 cgroup_disable= [KNL] Disable a particular controller500 cgroup_disable= [KNL] Disable a particular controller or optional feature
501 Format: {name of the controller(s) to disable}501 Format: {name of the controller(s) or feature(s) to disable}
502 The effects of cgroup_disable=foo are:502 The effects of cgroup_disable=foo are:
503 - foo isn't auto-mounted if you mount all cgroups in503 - foo isn't auto-mounted if you mount all cgroups in
504 a single hierarchy504 a single hierarchy
505 - foo isn't visible as an individually mountable505 - foo isn't visible as an individually mountable
506 subsystem506 subsystem
507 - if foo is an optional feature then the feature is
508 disabled and corresponding cgroup files are not
509 created
507 {Currently only "memory" controller deal with this and510 {Currently only "memory" controller deal with this and
508 cut the overhead, others just disable the usage. So511 cut the overhead, others just disable the usage. So
509 only cgroup_disable=memory is actually worthy}512 only cgroup_disable=memory is actually worthy}
513 Specifying "pressure" disables per-cgroup pressure
514 stall information accounting feature
510 515
511 cgroup_no_v1= [KNL] Disable cgroup controllers and named hierarchies in v1516 cgroup_no_v1= [KNL] Disable cgroup controllers and named hierarchies in v1
512 Format: { { controller | "all" | "named" }517 Format: { { controller | "all" | "named" }
include/linux/cgroup-defs.h+1−0
@@ -113,6 +113,7 @@ enum { · 112 unmodified lines
113 CFTYPE_NO_PREFIX = (1 << 3), /* (DON'T USE FOR NEW FILES) no subsys prefix */113 CFTYPE_NO_PREFIX = (1 << 3), /* (DON'T USE FOR NEW FILES) no subsys prefix */
114 CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */114 CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */
115 CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */115 CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */
116 CFTYPE_PRESSURE = (1 << 6), /* only if pressure feature is enabled */
116 117
117 /* internal flags, do not use outside cgroup core proper */118 /* internal flags, do not use outside cgroup core proper */
118 __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */119 __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */
include/linux/cgroup.h+7−0
@@ -676,6 +676,8 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) · 675 unmodified lines
676 return &cgrp->psi;676 return &cgrp->psi;
677}677}
678 678
679bool cgroup_psi_enabled(void);
680
679static inline void cgroup_init_kthreadd(void)681static inline void cgroup_init_kthreadd(void)
680{682{
681 /*683 /*
@@ -735,6 +737,11 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) · 53 unmodified lines
735 return NULL;737 return NULL;
736}738}
737 739
740static inline bool cgroup_psi_enabled(void)
741{
742 return false;
743}
744
738static inline bool task_under_cgroup_hierarchy(struct task_struct *task,745static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
739 struct cgroup *ancestor)746 struct cgroup *ancestor)
740{747{
kernel/cgroup/cgroup.c+48−0
@@ -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,
@@ -3631,6 +3647,18 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) · 3416 unmodified lines
3631{3647{
3632 psi_trigger_replace(&of->priv, NULL);3648 psi_trigger_replace(&of->priv, NULL);
3633}3649}
3650
3651bool cgroup_psi_enabled(void)
3652{
3653 return (cgroup_feature_disable_mask & (1 << OPT_FEATURE_PRESSURE)) == 0;
3654}
3655
3656#else /* CONFIG_PSI */
3657bool cgroup_psi_enabled(void)
3658{
3659 return false;
3660}
3661
3634#endif /* CONFIG_PSI */3662#endif /* CONFIG_PSI */
3635 3663
3636static int cgroup_freeze_show(struct seq_file *seq, void *v)3664static int cgroup_freeze_show(struct seq_file *seq, void *v)
@@ -3955,6 +3983,8 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, · 318 unmodified lines
3955restart:3983restart:
3956 for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {3984 for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {
3957 /* does cft->flags tell us to skip this file on @cgrp? */3985 /* does cft->flags tell us to skip this file on @cgrp? */
3986 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
3987 continue;
3958 if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))3988 if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))
3959 continue;3989 continue;
3960 if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp))3990 if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp))
@@ -4032,6 +4062,9 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) · 71 unmodified lines
4032 4062
4033 WARN_ON(cft->ss || cft->kf_ops);4063 WARN_ON(cft->ss || cft->kf_ops);
4034 4064
4065 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
4066 continue;
4067
4035 if (cft->seq_start)4068 if (cft->seq_start)
4036 kf_ops = &cgroup_kf_ops;4069 kf_ops = &cgroup_kf_ops;
4037 else4070 else
@@ -4945,6 +4978,7 @@ static struct cftype cgroup_base_files[] = { · 907 unmodified lines
4945#ifdef CONFIG_PSI4978#ifdef CONFIG_PSI
4946 {4979 {
4947 .name = "io.pressure",4980 .name = "io.pressure",
4981 .flags = CFTYPE_PRESSURE,
4948 .seq_show = cgroup_io_pressure_show,4982 .seq_show = cgroup_io_pressure_show,
4949 .write = cgroup_io_pressure_write,4983 .write = cgroup_io_pressure_write,
4950 .poll = cgroup_pressure_poll,4984 .poll = cgroup_pressure_poll,
@@ -4952,6 +4986,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
4952 },4986 },
4953 {4987 {
4954 .name = "memory.pressure",4988 .name = "memory.pressure",
4989 .flags = CFTYPE_PRESSURE,
4955 .seq_show = cgroup_memory_pressure_show,4990 .seq_show = cgroup_memory_pressure_show,
4956 .write = cgroup_memory_pressure_write,4991 .write = cgroup_memory_pressure_write,
4957 .poll = cgroup_pressure_poll,4992 .poll = cgroup_pressure_poll,
@@ -4959,6 +4994,7 @@ static struct cftype cgroup_base_files[] = { · 1 unmodified line
4959 },4994 },
4960 {4995 {
4961 .name = "cpu.pressure",4996 .name = "cpu.pressure",
4997 .flags = CFTYPE_PRESSURE,
4962 .seq_show = cgroup_cpu_pressure_show,4998 .seq_show = cgroup_cpu_pressure_show,
4963 .write = cgroup_cpu_pressure_write,4999 .write = cgroup_cpu_pressure_write,
4964 .poll = cgroup_pressure_poll,5000 .poll = cgroup_pressure_poll,
@@ -6313,6 +6349,15 @@ static int __init cgroup_disable(char *str) · 1348 unmodified lines
6313 pr_info("Disabling %s control group subsystem\n",6349 pr_info("Disabling %s control group subsystem\n",
6314 ss->name);6350 ss->name);
6315 }6351 }
6352
6353 for (i = 0; i < OPT_FEATURE_COUNT; i++) {
6354 if (strcmp(token, cgroup_opt_feature_names[i]))
6355 continue;
6356 cgroup_feature_disable_mask |= 1 << i;
6357 pr_info("Disabling %s control group feature\n",
6358 cgroup_opt_feature_names[i]);
6359 break;
6360 }
6316 }6361 }
6317 return 1;6362 return 1;
6318}6363}
@@ -6611,6 +6656,9 @@ static ssize_t show_delegatable_files(struct cftype *files, char *buf, · 292 unmodified lines
6611 if (!(cft->flags & CFTYPE_NS_DELEGATABLE))6656 if (!(cft->flags & CFTYPE_NS_DELEGATABLE))
6612 continue;6657 continue;
6613 6658
6659 if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled())
6660 continue;
6661
6614 if (prefix)6662 if (prefix)
6615 ret += snprintf(buf + ret, size - ret, "%s.", prefix);6663 ret += snprintf(buf + ret, size - ret, "%s.", prefix);
6616 6664
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;
@@ -211,6 +212,9 @@ void __init psi_init(void) · 57 unmodified lines
211 return;212 return;
212 }213 }
213 214
215 if (!cgroup_psi_enabled())
216 static_branch_disable(&psi_cgroups_enabled);
217
214 psi_period = jiffies_to_nsecs(PSI_FREQ);218 psi_period = jiffies_to_nsecs(PSI_FREQ);
215 group_init(&psi_system);219 group_init(&psi_system);
216}220}
@@ -744,23 +748,23 @@ static void psi_group_change(struct psi_group *group, int cpu, · 527 unmodified lines
744 748
745static struct psi_group *iterate_groups(struct task_struct *task, void **iter)749static struct psi_group *iterate_groups(struct task_struct *task, void **iter)
746{750{
751 if (*iter == &psi_system)
752 return NULL;
753
747#ifdef CONFIG_CGROUPS754#ifdef CONFIG_CGROUPS
748 struct cgroup *cgroup = NULL;755 if (static_branch_likely(&psi_cgroups_enabled)) {
756 struct cgroup *cgroup = NULL;
749 757
750 if (!*iter)758 if (!*iter)
751 cgroup = task->cgroups->dfl_cgrp;759 cgroup = task->cgroups->dfl_cgrp;
752 else if (*iter == &psi_system)760 else
753 return NULL;761 cgroup = cgroup_parent(*iter);
754 else
755 cgroup = cgroup_parent(*iter);
756 762
757 if (cgroup && cgroup_parent(cgroup)) {763 if (cgroup && cgroup_parent(cgroup)) {
758 *iter = cgroup;764 *iter = cgroup;
759 return cgroup_psi(cgroup);765 return cgroup_psi(cgroup);
766 }
760 }767 }
761#else
762 if (*iter)
763 return NULL;
764#endif768#endif
765 *iter = &psi_system;769 *iter = &psi_system;
766 return &psi_system;770 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