diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2011-07-26 19:08:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 19:49:42 -0400 |
commit | bb2a0de92c891b8feeedc0178acb3ae009d899a8 (patch) | |
tree | c2c0b3ad66c8da0e48c021927b2d747fb08b7ef3 /mm/memcontrol.c | |
parent | 1f4c025b5a5520fd2571244196b1b01ad96d18f6 (diff) |
memcg: consolidate memory cgroup lru stat functions
In mm/memcontrol.c, there are many lru stat functions as..
mem_cgroup_zone_nr_lru_pages
mem_cgroup_node_nr_file_lru_pages
mem_cgroup_nr_file_lru_pages
mem_cgroup_node_nr_anon_lru_pages
mem_cgroup_nr_anon_lru_pages
mem_cgroup_node_nr_unevictable_lru_pages
mem_cgroup_nr_unevictable_lru_pages
mem_cgroup_node_nr_lru_pages
mem_cgroup_nr_lru_pages
mem_cgroup_get_local_zonestat
Some of them are under #ifdef MAX_NUMNODES >1 and others are not.
This seems bad. This patch consolidates all functions into
mem_cgroup_zone_nr_lru_pages()
mem_cgroup_node_nr_lru_pages()
mem_cgroup_nr_lru_pages()
For these functions, "which LRU?" information is passed by a mask.
example:
mem_cgroup_nr_lru_pages(mem, BIT(LRU_ACTIVE_ANON))
And I added some macro as ALL_LRU, ALL_LRU_FILE, ALL_LRU_ANON.
example:
mem_cgroup_nr_lru_pages(mem, ALL_LRU)
BTW, considering layout of NUMA memory placement of counters, this patch seems
to be better.
Now, when we gather all LRU information, we scan in following orer
for_each_lru -> for_each_node -> for_each_zone.
This means we'll touch cache lines in different node in turn.
After patch, we'll scan
for_each_node -> for_each_zone -> for_each_lru(mask)
Then, we'll gather information in the same cacheline at once.
[akpm@linux-foundation.org: fix warnigns, build error]
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Ying Han <yinghan@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 176 |
1 files changed, 49 insertions, 127 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 506d116a7d33..85599662bd90 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -636,27 +636,44 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, | |||
636 | preempt_enable(); | 636 | preempt_enable(); |
637 | } | 637 | } |
638 | 638 | ||
639 | static unsigned long | 639 | unsigned long |
640 | mem_cgroup_get_zonestat_node(struct mem_cgroup *mem, int nid, enum lru_list idx) | 640 | mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *mem, int nid, int zid, |
641 | unsigned int lru_mask) | ||
641 | { | 642 | { |
642 | struct mem_cgroup_per_zone *mz; | 643 | struct mem_cgroup_per_zone *mz; |
644 | enum lru_list l; | ||
645 | unsigned long ret = 0; | ||
646 | |||
647 | mz = mem_cgroup_zoneinfo(mem, nid, zid); | ||
648 | |||
649 | for_each_lru(l) { | ||
650 | if (BIT(l) & lru_mask) | ||
651 | ret += MEM_CGROUP_ZSTAT(mz, l); | ||
652 | } | ||
653 | return ret; | ||
654 | } | ||
655 | |||
656 | static unsigned long | ||
657 | mem_cgroup_node_nr_lru_pages(struct mem_cgroup *mem, | ||
658 | int nid, unsigned int lru_mask) | ||
659 | { | ||
643 | u64 total = 0; | 660 | u64 total = 0; |
644 | int zid; | 661 | int zid; |
645 | 662 | ||
646 | for (zid = 0; zid < MAX_NR_ZONES; zid++) { | 663 | for (zid = 0; zid < MAX_NR_ZONES; zid++) |
647 | mz = mem_cgroup_zoneinfo(mem, nid, zid); | 664 | total += mem_cgroup_zone_nr_lru_pages(mem, nid, zid, lru_mask); |
648 | total += MEM_CGROUP_ZSTAT(mz, idx); | 665 | |
649 | } | ||
650 | return total; | 666 | return total; |
651 | } | 667 | } |
652 | static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem, | 668 | |
653 | enum lru_list idx) | 669 | static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *mem, |
670 | unsigned int lru_mask) | ||
654 | { | 671 | { |
655 | int nid; | 672 | int nid; |
656 | u64 total = 0; | 673 | u64 total = 0; |
657 | 674 | ||
658 | for_each_online_node(nid) | 675 | for_each_node_state(nid, N_HIGH_MEMORY) |
659 | total += mem_cgroup_get_zonestat_node(mem, nid, idx); | 676 | total += mem_cgroup_node_nr_lru_pages(mem, nid, lru_mask); |
660 | return total; | 677 | return total; |
661 | } | 678 | } |
662 | 679 | ||
@@ -1077,8 +1094,8 @@ static int calc_inactive_ratio(struct mem_cgroup *memcg, unsigned long *present_ | |||
1077 | unsigned long gb; | 1094 | unsigned long gb; |
1078 | unsigned long inactive_ratio; | 1095 | unsigned long inactive_ratio; |
1079 | 1096 | ||
1080 | inactive = mem_cgroup_get_local_zonestat(memcg, LRU_INACTIVE_ANON); | 1097 | inactive = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_INACTIVE_ANON)); |
1081 | active = mem_cgroup_get_local_zonestat(memcg, LRU_ACTIVE_ANON); | 1098 | active = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_ACTIVE_ANON)); |
1082 | 1099 | ||
1083 | gb = (inactive + active) >> (30 - PAGE_SHIFT); | 1100 | gb = (inactive + active) >> (30 - PAGE_SHIFT); |
1084 | if (gb) | 1101 | if (gb) |
@@ -1117,109 +1134,12 @@ int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) | |||
1117 | unsigned long active; | 1134 | unsigned long active; |
1118 | unsigned long inactive; | 1135 | unsigned long inactive; |
1119 | 1136 | ||
1120 | inactive = mem_cgroup_get_local_zonestat(memcg, LRU_INACTIVE_FILE); | 1137 | inactive = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_INACTIVE_FILE)); |
1121 | active = mem_cgroup_get_local_zonestat(memcg, LRU_ACTIVE_FILE); | 1138 | active = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_ACTIVE_FILE)); |
1122 | 1139 | ||
1123 | return (active > inactive); | 1140 | return (active > inactive); |
1124 | } | 1141 | } |
1125 | 1142 | ||
1126 | unsigned long mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, | ||
1127 | struct zone *zone, | ||
1128 | enum lru_list lru) | ||
1129 | { | ||
1130 | int nid = zone_to_nid(zone); | ||
1131 | int zid = zone_idx(zone); | ||
1132 | struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(memcg, nid, zid); | ||
1133 | |||
1134 | return MEM_CGROUP_ZSTAT(mz, lru); | ||
1135 | } | ||
1136 | |||
1137 | static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg, | ||
1138 | int nid) | ||
1139 | { | ||
1140 | unsigned long ret; | ||
1141 | |||
1142 | ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_FILE) + | ||
1143 | mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_FILE); | ||
1144 | |||
1145 | return ret; | ||
1146 | } | ||
1147 | |||
1148 | static unsigned long mem_cgroup_node_nr_anon_lru_pages(struct mem_cgroup *memcg, | ||
1149 | int nid) | ||
1150 | { | ||
1151 | unsigned long ret; | ||
1152 | |||
1153 | ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_ANON) + | ||
1154 | mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_ANON); | ||
1155 | return ret; | ||
1156 | } | ||
1157 | |||
1158 | #if MAX_NUMNODES > 1 | ||
1159 | static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg) | ||
1160 | { | ||
1161 | u64 total = 0; | ||
1162 | int nid; | ||
1163 | |||
1164 | for_each_node_state(nid, N_HIGH_MEMORY) | ||
1165 | total += mem_cgroup_node_nr_file_lru_pages(memcg, nid); | ||
1166 | |||
1167 | return total; | ||
1168 | } | ||
1169 | |||
1170 | static unsigned long mem_cgroup_nr_anon_lru_pages(struct mem_cgroup *memcg) | ||
1171 | { | ||
1172 | u64 total = 0; | ||
1173 | int nid; | ||
1174 | |||
1175 | for_each_node_state(nid, N_HIGH_MEMORY) | ||
1176 | total += mem_cgroup_node_nr_anon_lru_pages(memcg, nid); | ||
1177 | |||
1178 | return total; | ||
1179 | } | ||
1180 | |||
1181 | static unsigned long | ||
1182 | mem_cgroup_node_nr_unevictable_lru_pages(struct mem_cgroup *memcg, int nid) | ||
1183 | { | ||
1184 | return mem_cgroup_get_zonestat_node(memcg, nid, LRU_UNEVICTABLE); | ||
1185 | } | ||
1186 | |||
1187 | static unsigned long | ||
1188 | mem_cgroup_nr_unevictable_lru_pages(struct mem_cgroup *memcg) | ||
1189 | { | ||
1190 | u64 total = 0; | ||
1191 | int nid; | ||
1192 | |||
1193 | for_each_node_state(nid, N_HIGH_MEMORY) | ||
1194 | total += mem_cgroup_node_nr_unevictable_lru_pages(memcg, nid); | ||
1195 | |||
1196 | return total; | ||
1197 | } | ||
1198 | |||
1199 | static unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg, | ||
1200 | int nid) | ||
1201 | { | ||
1202 | enum lru_list l; | ||
1203 | u64 total = 0; | ||
1204 | |||
1205 | for_each_lru(l) | ||
1206 | total += mem_cgroup_get_zonestat_node(memcg, nid, l); | ||
1207 | |||
1208 | return total; | ||
1209 | } | ||
1210 | |||
1211 | static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg) | ||
1212 | { | ||
1213 | u64 total = 0; | ||
1214 | int nid; | ||
1215 | |||
1216 | for_each_node_state(nid, N_HIGH_MEMORY) | ||
1217 | total += mem_cgroup_node_nr_lru_pages(memcg, nid); | ||
1218 | |||
1219 | return total; | ||
1220 | } | ||
1221 | #endif /* CONFIG_NUMA */ | ||
1222 | |||
1223 | struct zone_reclaim_stat *mem_cgroup_get_reclaim_stat(struct mem_cgroup *memcg, | 1143 | struct zone_reclaim_stat *mem_cgroup_get_reclaim_stat(struct mem_cgroup *memcg, |
1224 | struct zone *zone) | 1144 | struct zone *zone) |
1225 | { | 1145 | { |
@@ -1576,11 +1496,11 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) | |||
1576 | static bool test_mem_cgroup_node_reclaimable(struct mem_cgroup *mem, | 1496 | static bool test_mem_cgroup_node_reclaimable(struct mem_cgroup *mem, |
1577 | int nid, bool noswap) | 1497 | int nid, bool noswap) |
1578 | { | 1498 | { |
1579 | if (mem_cgroup_node_nr_file_lru_pages(mem, nid)) | 1499 | if (mem_cgroup_node_nr_lru_pages(mem, nid, LRU_ALL_FILE)) |
1580 | return true; | 1500 | return true; |
1581 | if (noswap || !total_swap_pages) | 1501 | if (noswap || !total_swap_pages) |
1582 | return false; | 1502 | return false; |
1583 | if (mem_cgroup_node_nr_anon_lru_pages(mem, nid)) | 1503 | if (mem_cgroup_node_nr_lru_pages(mem, nid, LRU_ALL_ANON)) |
1584 | return true; | 1504 | return true; |
1585 | return false; | 1505 | return false; |
1586 | 1506 | ||
@@ -4151,15 +4071,15 @@ mem_cgroup_get_local_stat(struct mem_cgroup *mem, struct mcs_total_stat *s) | |||
4151 | s->stat[MCS_PGMAJFAULT] += val; | 4071 | s->stat[MCS_PGMAJFAULT] += val; |
4152 | 4072 | ||
4153 | /* per zone stat */ | 4073 | /* per zone stat */ |
4154 | val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON); | 4074 | val = mem_cgroup_nr_lru_pages(mem, BIT(LRU_INACTIVE_ANON)); |
4155 | s->stat[MCS_INACTIVE_ANON] += val * PAGE_SIZE; | 4075 | s->stat[MCS_INACTIVE_ANON] += val * PAGE_SIZE; |
4156 | val = mem_cgroup_get_local_zonestat(mem, LRU_ACTIVE_ANON); | 4076 | val = mem_cgroup_nr_lru_pages(mem, BIT(LRU_ACTIVE_ANON)); |
4157 | s->stat[MCS_ACTIVE_ANON] += val * PAGE_SIZE; | 4077 | s->stat[MCS_ACTIVE_ANON] += val * PAGE_SIZE; |
4158 | val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_FILE); | 4078 | val = mem_cgroup_nr_lru_pages(mem, BIT(LRU_INACTIVE_FILE)); |
4159 | s->stat[MCS_INACTIVE_FILE] += val * PAGE_SIZE; | 4079 | s->stat[MCS_INACTIVE_FILE] += val * PAGE_SIZE; |
4160 | val = mem_cgroup_get_local_zonestat(mem, LRU_ACTIVE_FILE); | 4080 | val = mem_cgroup_nr_lru_pages(mem, BIT(LRU_ACTIVE_FILE)); |
4161 | s->stat[MCS_ACTIVE_FILE] += val * PAGE_SIZE; | 4081 | s->stat[MCS_ACTIVE_FILE] += val * PAGE_SIZE; |
4162 | val = mem_cgroup_get_local_zonestat(mem, LRU_UNEVICTABLE); | 4082 | val = mem_cgroup_nr_lru_pages(mem, BIT(LRU_UNEVICTABLE)); |
4163 | s->stat[MCS_UNEVICTABLE] += val * PAGE_SIZE; | 4083 | s->stat[MCS_UNEVICTABLE] += val * PAGE_SIZE; |
4164 | } | 4084 | } |
4165 | 4085 | ||
@@ -4181,35 +4101,37 @@ static int mem_control_numa_stat_show(struct seq_file *m, void *arg) | |||
4181 | struct cgroup *cont = m->private; | 4101 | struct cgroup *cont = m->private; |
4182 | struct mem_cgroup *mem_cont = mem_cgroup_from_cont(cont); | 4102 | struct mem_cgroup *mem_cont = mem_cgroup_from_cont(cont); |
4183 | 4103 | ||
4184 | total_nr = mem_cgroup_nr_lru_pages(mem_cont); | 4104 | total_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL); |
4185 | seq_printf(m, "total=%lu", total_nr); | 4105 | seq_printf(m, "total=%lu", total_nr); |
4186 | for_each_node_state(nid, N_HIGH_MEMORY) { | 4106 | for_each_node_state(nid, N_HIGH_MEMORY) { |
4187 | node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid); | 4107 | node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid, LRU_ALL); |
4188 | seq_printf(m, " N%d=%lu", nid, node_nr); | 4108 | seq_printf(m, " N%d=%lu", nid, node_nr); |
4189 | } | 4109 | } |
4190 | seq_putc(m, '\n'); | 4110 | seq_putc(m, '\n'); |
4191 | 4111 | ||
4192 | file_nr = mem_cgroup_nr_file_lru_pages(mem_cont); | 4112 | file_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL_FILE); |
4193 | seq_printf(m, "file=%lu", file_nr); | 4113 | seq_printf(m, "file=%lu", file_nr); |
4194 | for_each_node_state(nid, N_HIGH_MEMORY) { | 4114 | for_each_node_state(nid, N_HIGH_MEMORY) { |
4195 | node_nr = mem_cgroup_node_nr_file_lru_pages(mem_cont, nid); | 4115 | node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid, |
4116 | LRU_ALL_FILE); | ||
4196 | seq_printf(m, " N%d=%lu", nid, node_nr); | 4117 | seq_printf(m, " N%d=%lu", nid, node_nr); |
4197 | } | 4118 | } |
4198 | seq_putc(m, '\n'); | 4119 | seq_putc(m, '\n'); |
4199 | 4120 | ||
4200 | anon_nr = mem_cgroup_nr_anon_lru_pages(mem_cont); | 4121 | anon_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL_ANON); |
4201 | seq_printf(m, "anon=%lu", anon_nr); | 4122 | seq_printf(m, "anon=%lu", anon_nr); |
4202 | for_each_node_state(nid, N_HIGH_MEMORY) { | 4123 | for_each_node_state(nid, N_HIGH_MEMORY) { |
4203 | node_nr = mem_cgroup_node_nr_anon_lru_pages(mem_cont, nid); | 4124 | node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid, |
4125 | LRU_ALL_ANON); | ||
4204 | seq_printf(m, " N%d=%lu", nid, node_nr); | 4126 | seq_printf(m, " N%d=%lu", nid, node_nr); |
4205 | } | 4127 | } |
4206 | seq_putc(m, '\n'); | 4128 | seq_putc(m, '\n'); |
4207 | 4129 | ||
4208 | unevictable_nr = mem_cgroup_nr_unevictable_lru_pages(mem_cont); | 4130 | unevictable_nr = mem_cgroup_nr_lru_pages(mem_cont, BIT(LRU_UNEVICTABLE)); |
4209 | seq_printf(m, "unevictable=%lu", unevictable_nr); | 4131 | seq_printf(m, "unevictable=%lu", unevictable_nr); |
4210 | for_each_node_state(nid, N_HIGH_MEMORY) { | 4132 | for_each_node_state(nid, N_HIGH_MEMORY) { |
4211 | node_nr = mem_cgroup_node_nr_unevictable_lru_pages(mem_cont, | 4133 | node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid, |
4212 | nid); | 4134 | BIT(LRU_UNEVICTABLE)); |
4213 | seq_printf(m, " N%d=%lu", nid, node_nr); | 4135 | seq_printf(m, " N%d=%lu", nid, node_nr); |
4214 | } | 4136 | } |
4215 | seq_putc(m, '\n'); | 4137 | seq_putc(m, '\n'); |