summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2013-04-29 18:07:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:33 -0400
commit19f39402864ea3935b36ab1066c6283d6ea53f44 (patch)
tree2a073f80c676db471735652122c9ac791adbd9d0 /mm
parent5f57816197186378449b848e99ca9cf41a0055f1 (diff)
memcg: simplify mem_cgroup_iter
The current implementation of mem_cgroup_iter has to consider both css and memcg to find out whether no group has been found (css==NULL - aka the loop is completed) and that no memcg is associated with the found node (!memcg - aka css_tryget failed because the group is no longer alive). This leads to awkward tweaks like tests for css && !memcg to skip the current node. It will be much easier if we got rid off css variable altogether and only rely on memcg. In order to do that the iteration part has to skip dead nodes. This sounds natural to me and as a nice side effect we will get a simple invariant that memcg is always alive when non-NULL and all nodes have been visited otherwise. We could get rid of the surrounding while loop but keep it in for now to make review easier. It will go away in the following patch. Signed-off-by: Michal Hocko <mhocko@suse.cz> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Li Zefan <lizefan@huawei.com> Cc: Ying Han <yinghan@google.com> Cc: Tejun Heo <htejun@gmail.com> Cc: Glauber Costa <glommer@parallels.com> 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.c52
1 files changed, 25 insertions, 27 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 408a5c75d77d..614d0d9c0deb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1116,7 +1116,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
1116 rcu_read_lock(); 1116 rcu_read_lock();
1117 while (!memcg) { 1117 while (!memcg) {
1118 struct mem_cgroup_reclaim_iter *uninitialized_var(iter); 1118 struct mem_cgroup_reclaim_iter *uninitialized_var(iter);
1119 struct cgroup_subsys_state *css = NULL;
1120 1119
1121 if (reclaim) { 1120 if (reclaim) {
1122 int nid = zone_to_nid(reclaim->zone); 1121 int nid = zone_to_nid(reclaim->zone);
@@ -1159,51 +1158,50 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
1159 * explicit visit. 1158 * explicit visit.
1160 */ 1159 */
1161 if (!last_visited) { 1160 if (!last_visited) {
1162 css = &root->css; 1161 memcg = root;
1163 } else { 1162 } else {
1164 struct cgroup *prev_cgroup, *next_cgroup; 1163 struct cgroup *prev_cgroup, *next_cgroup;
1165 1164
1166 prev_cgroup = (last_visited == root) ? NULL 1165 prev_cgroup = (last_visited == root) ? NULL
1167 : last_visited->css.cgroup; 1166 : last_visited->css.cgroup;
1168 next_cgroup = cgroup_next_descendant_pre(prev_cgroup, 1167skip_node:
1169 root->css.cgroup); 1168 next_cgroup = cgroup_next_descendant_pre(
1170 if (next_cgroup) 1169 prev_cgroup, root->css.cgroup);
1171 css = cgroup_subsys_state(next_cgroup,
1172 mem_cgroup_subsys_id);
1173 }
1174 1170
1175 /* 1171 /*
1176 * Even if we found a group we have to make sure it is alive. 1172 * Even if we found a group we have to make sure it is
1177 * css && !memcg means that the groups should be skipped and 1173 * alive. css && !memcg means that the groups should be
1178 * we should continue the tree walk. 1174 * skipped and we should continue the tree walk.
1179 * last_visited css is safe to use because it is protected by 1175 * last_visited css is safe to use because it is
1180 * css_get and the tree walk is rcu safe. 1176 * protected by css_get and the tree walk is rcu safe.
1181 */ 1177 */
1182 if (css == &root->css || (css && css_tryget(css))) 1178 if (next_cgroup) {
1183 memcg = mem_cgroup_from_css(css); 1179 struct mem_cgroup *mem = mem_cgroup_from_cont(
1180 next_cgroup);
1181 if (css_tryget(&mem->css))
1182 memcg = mem;
1183 else {
1184 prev_cgroup = next_cgroup;
1185 goto skip_node;
1186 }
1187 }
1188 }
1184 1189
1185 if (reclaim) { 1190 if (reclaim) {
1186 struct mem_cgroup *curr = memcg;
1187
1188 if (last_visited) 1191 if (last_visited)
1189 css_put(&last_visited->css); 1192 css_put(&last_visited->css);
1190 1193
1191 if (css && !memcg) 1194 iter->last_visited = memcg;
1192 curr = mem_cgroup_from_css(css);
1193
1194 iter->last_visited = curr;
1195 smp_wmb(); 1195 smp_wmb();
1196 iter->last_dead_count = dead_count; 1196 iter->last_dead_count = dead_count;
1197 1197
1198 if (!css) 1198 if (!memcg)
1199 iter->generation++; 1199 iter->generation++;
1200 else if (!prev && memcg) 1200 else if (!prev && memcg)
1201 reclaim->generation = iter->generation; 1201 reclaim->generation = iter->generation;
1202 } else if (css && !memcg) {
1203 last_visited = mem_cgroup_from_css(css);
1204 } 1202 }
1205 1203
1206 if (prev && !css) 1204 if (prev && !memcg)
1207 goto out_unlock; 1205 goto out_unlock;
1208 } 1206 }
1209out_unlock: 1207out_unlock: