aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2011-07-26 19:08:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 19:49:42 -0400
commitbb2a0de92c891b8feeedc0178acb3ae009d899a8 (patch)
treec2c0b3ad66c8da0e48c021927b2d747fb08b7ef3 /mm/memcontrol.c
parent1f4c025b5a5520fd2571244196b1b01ad96d18f6 (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.c176
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
639static unsigned long 639unsigned long
640mem_cgroup_get_zonestat_node(struct mem_cgroup *mem, int nid, enum lru_list idx) 640mem_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
656static unsigned long
657mem_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}
652static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem, 668
653 enum lru_list idx) 669static 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
1126unsigned 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
1137static 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
1148static 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
1159static 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
1170static 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
1181static unsigned long
1182mem_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
1187static unsigned long
1188mem_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
1199static 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
1211static 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
1223struct zone_reclaim_stat *mem_cgroup_get_reclaim_stat(struct mem_cgroup *memcg, 1143struct 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)
1576static bool test_mem_cgroup_node_reclaimable(struct mem_cgroup *mem, 1496static 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');