diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2012-05-29 18:07:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 19:22:28 -0400 |
commit | af7c4b0ec257ea9abb9c6749dd5a5ba0b8fae1fd (patch) | |
tree | f5abf6b2e7301fc0daa61de46021b1c102cdd4cc /mm | |
parent | fad02c2de0623fc6d4ff12ca72b60ea521118681 (diff) |
mm: memcg: print statistics from live counters
Directly print statistics and event counters instead of going through an
intermediate accumulation stage into a separate array, which used to
require defining statistic items in more than one place.
[akpm@linux-foundation.org: checkpatch fixes]
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.cz>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Ying Han <yinghan@google.com>
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 | 168 |
1 files changed, 66 insertions, 102 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 1118e02a40b6..35e008e25422 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -91,6 +91,13 @@ enum mem_cgroup_stat_index { | |||
91 | MEM_CGROUP_STAT_NSTATS, | 91 | MEM_CGROUP_STAT_NSTATS, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static const char * const mem_cgroup_stat_names[] = { | ||
95 | "cache", | ||
96 | "rss", | ||
97 | "mapped_file", | ||
98 | "swap", | ||
99 | }; | ||
100 | |||
94 | enum mem_cgroup_events_index { | 101 | enum mem_cgroup_events_index { |
95 | MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */ | 102 | MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */ |
96 | MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */ | 103 | MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */ |
@@ -98,6 +105,14 @@ enum mem_cgroup_events_index { | |||
98 | MEM_CGROUP_EVENTS_PGMAJFAULT, /* # of major page-faults */ | 105 | MEM_CGROUP_EVENTS_PGMAJFAULT, /* # of major page-faults */ |
99 | MEM_CGROUP_EVENTS_NSTATS, | 106 | MEM_CGROUP_EVENTS_NSTATS, |
100 | }; | 107 | }; |
108 | |||
109 | static const char * const mem_cgroup_events_names[] = { | ||
110 | "pgpgin", | ||
111 | "pgpgout", | ||
112 | "pgfault", | ||
113 | "pgmajfault", | ||
114 | }; | ||
115 | |||
101 | /* | 116 | /* |
102 | * Per memcg event counter is incremented at every pagein/pageout. With THP, | 117 | * Per memcg event counter is incremented at every pagein/pageout. With THP, |
103 | * it will be incremated by the number of pages. This counter is used for | 118 | * it will be incremated by the number of pages. This counter is used for |
@@ -4037,92 +4052,6 @@ static int mem_cgroup_move_charge_write(struct cgroup *cgrp, | |||
4037 | } | 4052 | } |
4038 | #endif | 4053 | #endif |
4039 | 4054 | ||
4040 | |||
4041 | /* For read statistics */ | ||
4042 | enum { | ||
4043 | MCS_CACHE, | ||
4044 | MCS_RSS, | ||
4045 | MCS_FILE_MAPPED, | ||
4046 | MCS_SWAP, | ||
4047 | MCS_PGPGIN, | ||
4048 | MCS_PGPGOUT, | ||
4049 | MCS_PGFAULT, | ||
4050 | MCS_PGMAJFAULT, | ||
4051 | MCS_INACTIVE_ANON, | ||
4052 | MCS_ACTIVE_ANON, | ||
4053 | MCS_INACTIVE_FILE, | ||
4054 | MCS_ACTIVE_FILE, | ||
4055 | MCS_UNEVICTABLE, | ||
4056 | NR_MCS_STAT, | ||
4057 | }; | ||
4058 | |||
4059 | struct mcs_total_stat { | ||
4060 | s64 stat[NR_MCS_STAT]; | ||
4061 | }; | ||
4062 | |||
4063 | static const char *memcg_stat_strings[NR_MCS_STAT] = { | ||
4064 | "cache", | ||
4065 | "rss", | ||
4066 | "mapped_file", | ||
4067 | "swap", | ||
4068 | "pgpgin", | ||
4069 | "pgpgout", | ||
4070 | "pgfault", | ||
4071 | "pgmajfault", | ||
4072 | "inactive_anon", | ||
4073 | "active_anon", | ||
4074 | "inactive_file", | ||
4075 | "active_file", | ||
4076 | "unevictable", | ||
4077 | }; | ||
4078 | |||
4079 | static void | ||
4080 | mem_cgroup_get_local_stat(struct mem_cgroup *memcg, struct mcs_total_stat *s) | ||
4081 | { | ||
4082 | s64 val; | ||
4083 | |||
4084 | /* per cpu stat */ | ||
4085 | val = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_CACHE); | ||
4086 | s->stat[MCS_CACHE] += val * PAGE_SIZE; | ||
4087 | val = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_RSS); | ||
4088 | s->stat[MCS_RSS] += val * PAGE_SIZE; | ||
4089 | val = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED); | ||
4090 | s->stat[MCS_FILE_MAPPED] += val * PAGE_SIZE; | ||
4091 | val = mem_cgroup_read_events(memcg, MEM_CGROUP_EVENTS_PGPGIN); | ||
4092 | s->stat[MCS_PGPGIN] += val; | ||
4093 | val = mem_cgroup_read_events(memcg, MEM_CGROUP_EVENTS_PGPGOUT); | ||
4094 | s->stat[MCS_PGPGOUT] += val; | ||
4095 | if (do_swap_account) { | ||
4096 | val = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_SWAPOUT); | ||
4097 | s->stat[MCS_SWAP] += val * PAGE_SIZE; | ||
4098 | } | ||
4099 | val = mem_cgroup_read_events(memcg, MEM_CGROUP_EVENTS_PGFAULT); | ||
4100 | s->stat[MCS_PGFAULT] += val; | ||
4101 | val = mem_cgroup_read_events(memcg, MEM_CGROUP_EVENTS_PGMAJFAULT); | ||
4102 | s->stat[MCS_PGMAJFAULT] += val; | ||
4103 | |||
4104 | /* per zone stat */ | ||
4105 | val = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_INACTIVE_ANON)); | ||
4106 | s->stat[MCS_INACTIVE_ANON] += val * PAGE_SIZE; | ||
4107 | val = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_ACTIVE_ANON)); | ||
4108 | s->stat[MCS_ACTIVE_ANON] += val * PAGE_SIZE; | ||
4109 | val = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_INACTIVE_FILE)); | ||
4110 | s->stat[MCS_INACTIVE_FILE] += val * PAGE_SIZE; | ||
4111 | val = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_ACTIVE_FILE)); | ||
4112 | s->stat[MCS_ACTIVE_FILE] += val * PAGE_SIZE; | ||
4113 | val = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_UNEVICTABLE)); | ||
4114 | s->stat[MCS_UNEVICTABLE] += val * PAGE_SIZE; | ||
4115 | } | ||
4116 | |||
4117 | static void | ||
4118 | mem_cgroup_get_total_stat(struct mem_cgroup *memcg, struct mcs_total_stat *s) | ||
4119 | { | ||
4120 | struct mem_cgroup *iter; | ||
4121 | |||
4122 | for_each_mem_cgroup_tree(iter, memcg) | ||
4123 | mem_cgroup_get_local_stat(iter, s); | ||
4124 | } | ||
4125 | |||
4126 | #ifdef CONFIG_NUMA | 4055 | #ifdef CONFIG_NUMA |
4127 | static int mem_control_numa_stat_show(struct cgroup *cont, struct cftype *cft, | 4056 | static int mem_control_numa_stat_show(struct cgroup *cont, struct cftype *cft, |
4128 | struct seq_file *m) | 4057 | struct seq_file *m) |
@@ -4170,24 +4099,41 @@ static int mem_control_numa_stat_show(struct cgroup *cont, struct cftype *cft, | |||
4170 | } | 4099 | } |
4171 | #endif /* CONFIG_NUMA */ | 4100 | #endif /* CONFIG_NUMA */ |
4172 | 4101 | ||
4102 | static const char * const mem_cgroup_lru_names[] = { | ||
4103 | "inactive_anon", | ||
4104 | "active_anon", | ||
4105 | "inactive_file", | ||
4106 | "active_file", | ||
4107 | "unevictable", | ||
4108 | }; | ||
4109 | |||
4110 | static inline void mem_cgroup_lru_names_not_uptodate(void) | ||
4111 | { | ||
4112 | BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS); | ||
4113 | } | ||
4114 | |||
4173 | static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, | 4115 | static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, |
4174 | struct seq_file *m) | 4116 | struct seq_file *m) |
4175 | { | 4117 | { |
4176 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 4118 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); |
4177 | struct mcs_total_stat mystat; | 4119 | struct mem_cgroup *mi; |
4178 | int i; | 4120 | unsigned int i; |
4179 | |||
4180 | memset(&mystat, 0, sizeof(mystat)); | ||
4181 | mem_cgroup_get_local_stat(memcg, &mystat); | ||
4182 | |||
4183 | 4121 | ||
4184 | for (i = 0; i < NR_MCS_STAT; i++) { | 4122 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { |
4185 | if (i == MCS_SWAP && !do_swap_account) | 4123 | if (i == MEM_CGROUP_STAT_SWAPOUT && !do_swap_account) |
4186 | continue; | 4124 | continue; |
4187 | seq_printf(m, "%s %llu\n", memcg_stat_strings[i], | 4125 | seq_printf(m, "%s %ld\n", mem_cgroup_stat_names[i], |
4188 | (unsigned long long)mystat.stat[i]); | 4126 | mem_cgroup_read_stat(memcg, i) * PAGE_SIZE); |
4189 | } | 4127 | } |
4190 | 4128 | ||
4129 | for (i = 0; i < MEM_CGROUP_EVENTS_NSTATS; i++) | ||
4130 | seq_printf(m, "%s %lu\n", mem_cgroup_events_names[i], | ||
4131 | mem_cgroup_read_events(memcg, i)); | ||
4132 | |||
4133 | for (i = 0; i < NR_LRU_LISTS; i++) | ||
4134 | seq_printf(m, "%s %lu\n", mem_cgroup_lru_names[i], | ||
4135 | mem_cgroup_nr_lru_pages(memcg, BIT(i)) * PAGE_SIZE); | ||
4136 | |||
4191 | /* Hierarchical information */ | 4137 | /* Hierarchical information */ |
4192 | { | 4138 | { |
4193 | unsigned long long limit, memsw_limit; | 4139 | unsigned long long limit, memsw_limit; |
@@ -4198,13 +4144,31 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, | |||
4198 | memsw_limit); | 4144 | memsw_limit); |
4199 | } | 4145 | } |
4200 | 4146 | ||
4201 | memset(&mystat, 0, sizeof(mystat)); | 4147 | for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) { |
4202 | mem_cgroup_get_total_stat(memcg, &mystat); | 4148 | long long val = 0; |
4203 | for (i = 0; i < NR_MCS_STAT; i++) { | 4149 | |
4204 | if (i == MCS_SWAP && !do_swap_account) | 4150 | if (i == MEM_CGROUP_STAT_SWAPOUT && !do_swap_account) |
4205 | continue; | 4151 | continue; |
4206 | seq_printf(m, "total_%s %llu\n", memcg_stat_strings[i], | 4152 | for_each_mem_cgroup_tree(mi, memcg) |
4207 | (unsigned long long)mystat.stat[i]); | 4153 | val += mem_cgroup_read_stat(mi, i) * PAGE_SIZE; |
4154 | seq_printf(m, "total_%s %lld\n", mem_cgroup_stat_names[i], val); | ||
4155 | } | ||
4156 | |||
4157 | for (i = 0; i < MEM_CGROUP_EVENTS_NSTATS; i++) { | ||
4158 | unsigned long long val = 0; | ||
4159 | |||
4160 | for_each_mem_cgroup_tree(mi, memcg) | ||
4161 | val += mem_cgroup_read_events(mi, i); | ||
4162 | seq_printf(m, "total_%s %llu\n", | ||
4163 | mem_cgroup_events_names[i], val); | ||
4164 | } | ||
4165 | |||
4166 | for (i = 0; i < NR_LRU_LISTS; i++) { | ||
4167 | unsigned long long val = 0; | ||
4168 | |||
4169 | for_each_mem_cgroup_tree(mi, memcg) | ||
4170 | val += mem_cgroup_nr_lru_pages(mi, BIT(i)) * PAGE_SIZE; | ||
4171 | seq_printf(m, "total_%s %llu\n", mem_cgroup_lru_names[i], val); | ||
4208 | } | 4172 | } |
4209 | 4173 | ||
4210 | #ifdef CONFIG_DEBUG_VM | 4174 | #ifdef CONFIG_DEBUG_VM |