diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2016-01-20 18:03:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-20 20:09:18 -0500 |
commit | 587d9f726aaec52157e4156e50363dbe6cb82bdb (patch) | |
tree | bd3afd21baa9d5032fb30754aa88485f3ae64a2a /mm | |
parent | 44b7a8d33d666268062e0f725d5f14813a63a6ea (diff) |
mm: memcontrol: basic memory statistics in cgroup2 memory controller
Provide a cgroup2 memory.stat that provides statistics on LRU memory
and fault event counters. More consumers and breakdowns will follow.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memcontrol.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bf35bff282fc..98f4109bff6c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2767,6 +2767,18 @@ static unsigned long tree_stat(struct mem_cgroup *memcg, | |||
2767 | return val; | 2767 | return val; |
2768 | } | 2768 | } |
2769 | 2769 | ||
2770 | static unsigned long tree_events(struct mem_cgroup *memcg, | ||
2771 | enum mem_cgroup_events_index idx) | ||
2772 | { | ||
2773 | struct mem_cgroup *iter; | ||
2774 | unsigned long val = 0; | ||
2775 | |||
2776 | for_each_mem_cgroup_tree(iter, memcg) | ||
2777 | val += mem_cgroup_read_events(iter, idx); | ||
2778 | |||
2779 | return val; | ||
2780 | } | ||
2781 | |||
2770 | static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap) | 2782 | static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap) |
2771 | { | 2783 | { |
2772 | unsigned long val; | 2784 | unsigned long val; |
@@ -5096,6 +5108,57 @@ static int memory_events_show(struct seq_file *m, void *v) | |||
5096 | return 0; | 5108 | return 0; |
5097 | } | 5109 | } |
5098 | 5110 | ||
5111 | static int memory_stat_show(struct seq_file *m, void *v) | ||
5112 | { | ||
5113 | struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); | ||
5114 | int i; | ||
5115 | |||
5116 | /* | ||
5117 | * Provide statistics on the state of the memory subsystem as | ||
5118 | * well as cumulative event counters that show past behavior. | ||
5119 | * | ||
5120 | * This list is ordered following a combination of these gradients: | ||
5121 | * 1) generic big picture -> specifics and details | ||
5122 | * 2) reflecting userspace activity -> reflecting kernel heuristics | ||
5123 | * | ||
5124 | * Current memory state: | ||
5125 | */ | ||
5126 | |||
5127 | seq_printf(m, "anon %llu\n", | ||
5128 | (u64)tree_stat(memcg, MEM_CGROUP_STAT_RSS) * PAGE_SIZE); | ||
5129 | seq_printf(m, "file %llu\n", | ||
5130 | (u64)tree_stat(memcg, MEM_CGROUP_STAT_CACHE) * PAGE_SIZE); | ||
5131 | |||
5132 | seq_printf(m, "file_mapped %llu\n", | ||
5133 | (u64)tree_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED) * | ||
5134 | PAGE_SIZE); | ||
5135 | seq_printf(m, "file_dirty %llu\n", | ||
5136 | (u64)tree_stat(memcg, MEM_CGROUP_STAT_DIRTY) * | ||
5137 | PAGE_SIZE); | ||
5138 | seq_printf(m, "file_writeback %llu\n", | ||
5139 | (u64)tree_stat(memcg, MEM_CGROUP_STAT_WRITEBACK) * | ||
5140 | PAGE_SIZE); | ||
5141 | |||
5142 | for (i = 0; i < NR_LRU_LISTS; i++) { | ||
5143 | struct mem_cgroup *mi; | ||
5144 | unsigned long val = 0; | ||
5145 | |||
5146 | for_each_mem_cgroup_tree(mi, memcg) | ||
5147 | val += mem_cgroup_nr_lru_pages(mi, BIT(i)); | ||
5148 | seq_printf(m, "%s %llu\n", | ||
5149 | mem_cgroup_lru_names[i], (u64)val * PAGE_SIZE); | ||
5150 | } | ||
5151 | |||
5152 | /* Accumulated memory events */ | ||
5153 | |||
5154 | seq_printf(m, "pgfault %lu\n", | ||
5155 | tree_events(memcg, MEM_CGROUP_EVENTS_PGFAULT)); | ||
5156 | seq_printf(m, "pgmajfault %lu\n", | ||
5157 | tree_events(memcg, MEM_CGROUP_EVENTS_PGMAJFAULT)); | ||
5158 | |||
5159 | return 0; | ||
5160 | } | ||
5161 | |||
5099 | static struct cftype memory_files[] = { | 5162 | static struct cftype memory_files[] = { |
5100 | { | 5163 | { |
5101 | .name = "current", | 5164 | .name = "current", |
@@ -5126,6 +5189,11 @@ static struct cftype memory_files[] = { | |||
5126 | .file_offset = offsetof(struct mem_cgroup, events_file), | 5189 | .file_offset = offsetof(struct mem_cgroup, events_file), |
5127 | .seq_show = memory_events_show, | 5190 | .seq_show = memory_events_show, |
5128 | }, | 5191 | }, |
5192 | { | ||
5193 | .name = "stat", | ||
5194 | .flags = CFTYPE_NOT_ON_ROOT, | ||
5195 | .seq_show = memory_stat_show, | ||
5196 | }, | ||
5129 | { } /* terminate */ | 5197 | { } /* terminate */ |
5130 | }; | 5198 | }; |
5131 | 5199 | ||