summaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-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: