History

mm, memcg: consider subtrees in memory.events

memory.stat and other files already consider subtrees in their output, and we should too in order to not present an inconsistent interface. The current situation is fairly confusing, because people interacting with cgroups expect hierarchical behaviour in the vein of memory.stat, cgroup.events, and other files. For example, this causes confusion when debugging reclaim events under low, as currently these always read "0" at non-leaf memcg nodes, which frequently causes people to misdiagnose breach behaviour. The same confusion applies to other counters in this file when debugging issues. Aggregation is done at write time instead of at read-time since these counters aren't hot (unlike memory.stat which is per-page, so it does it at read time), and it makes sense to bundle this with the file notifications. After this patch, events are propagated up the hierarchy: [root@ktst ~]# cat /sys/fs/cgroup/system.slice/memory.events low 0 high 0 max 0 oom 0 oom_kill 0 [root@ktst ~]# systemd-run -p MemoryMax=1 true Running as unit: run-r251162a189fb4562b9dabfdc9b0422f5.service [root@ktst ~]# cat /sys/fs/cgroup/system.slice/memory.events low 0 high 0 max 7 oom 1 oom_kill 1 As this is a change in behaviour, this can be reverted to the old behaviour by mounting with the `memory_localevents' flag set. However, we use the new behaviour by default as there's a lack of evidence that there are any current users of memory.events that would find this change undesirable. akpm: this is a behaviour change, so Cc:stable. THis is so that forthcoming distros which use cgroup v2 are more likely to pick up the revised behaviour.

Chris Down committed 7 years ago

Commit 9852ae31 parent bc814264 files · +36 −4Browse files

Showing the changes to kernel (1 of 4 files). Show all

Unified · Split

kernel/cgroup/cgroup.c+14−2
@@ -1810,11 +1810,13 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node, · 1809 unmodified lines
18101810
18111811 enum cgroup2_param {
18121812 Opt_nsdelegate,
1813+ Opt_memory_localevents,
18131814 nr__cgroup2_params
18141815 };
18151816
18161817 static const struct fs_parameter_spec cgroup2_param_specs[] = {
1817− fsparam_flag ("nsdelegate", Opt_nsdelegate),
1818+ fsparam_flag("nsdelegate", Opt_nsdelegate),
1819+ fsparam_flag("memory_localevents", Opt_memory_localevents),
18181820 {}
18191821 };
18201822
@@ -1837,6 +1839,9 @@ static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param · 16 unmodified lines
18371839 case Opt_nsdelegate:
18381840 ctx->flags |= CGRP_ROOT_NS_DELEGATE;
18391841 return 0;
1842+ case Opt_memory_localevents:
1843+ ctx->flags |= CGRP_ROOT_MEMORY_LOCAL_EVENTS;
1844+ return 0;
18401845 }
18411846 return -EINVAL;
18421847 }
@@ -1848,6 +1853,11 @@ static void apply_cgroup_root_flags(unsigned int root_flags) · 5 unmodified lines
18481853 cgrp_dfl_root.flags |= CGRP_ROOT_NS_DELEGATE;
18491854 else
18501855 cgrp_dfl_root.flags &= ~CGRP_ROOT_NS_DELEGATE;
1856+
1857+ if (root_flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS)
1858+ cgrp_dfl_root.flags |= CGRP_ROOT_MEMORY_LOCAL_EVENTS;
1859+ else
1860+ cgrp_dfl_root.flags &= ~CGRP_ROOT_MEMORY_LOCAL_EVENTS;
18511861 }
18521862 }
18531863
@@ -1855,6 +1865,8 @@ static int cgroup_show_options(struct seq_file *seq, struct kernfs_root *kf_root · 1 unmodified line
18551865 {
18561866 if (cgrp_dfl_root.flags & CGRP_ROOT_NS_DELEGATE)
18571867 seq_puts(seq, ",nsdelegate");
1868+ if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS)
1869+ seq_puts(seq, ",memory_localevents");
18581870 return 0;
18591871 }
18601872
@@ -6325,7 +6337,7 @@ static struct kobj_attribute cgroup_delegate_attr = __ATTR_RO(delegate); · 4464 unmodified lines
63256337 static ssize_t features_show(struct kobject *kobj, struct kobj_attribute *attr,
63266338 char *buf)
63276339 {
6328− return snprintf(buf, PAGE_SIZE, "nsdelegate\n");
6340+ return snprintf(buf, PAGE_SIZE, "nsdelegate\nmemory_localevents\n");
63296341 }
63306342 static struct kobj_attribute cgroup_features_attr = __ATTR_RO(features);
63316343