On Fri 15-02-13 17:03:09, KAMEZAWA Hiroyuki wrote: [...] > > @@ -1158,31 +1161,74 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, > > > > mz = mem_cgroup_zoneinfo(root, nid, zid); > > iter = &mz->reclaim_iter[reclaim->priority]; > > - if (prev && reclaim->generation != iter->generation) > > - goto out_css_put; > > - id = iter->position; > > + spin_lock(&iter->iter_lock); > > + last_visited = iter->last_visited; > > + if (prev && reclaim->generation != iter->generation) { > > + if (last_visited) { > > + css_put(&last_visited->css); > > + iter->last_visited = NULL; > > + } > > + spin_unlock(&iter->iter_lock); > > + goto out_unlock; > > + } [...] > > + /* > > + * Even if we found a group we have to make sure it is alive. > > + * css && !memcg means that the groups should be skipped and > > + * we should continue the tree walk. > > + * last_visited css is safe to use because it is protected by > > + * css_get and the tree walk is rcu safe. > > + */ > > + if (css == &root->css || (css && css_tryget(css))) > > + memcg = mem_cgroup_from_css(css); > > > > if (reclaim) { > > - iter->position = id; > > + struct mem_cgroup *curr = memcg; > > + > > + if (last_visited) > > + css_put(&last_visited->css); > > + > > + if (css && !memcg) > > + curr = mem_cgroup_from_css(css); > > + > > + /* make sure that the cached memcg is not removed */ > > + if (curr) > > + css_get(&curr->css); > I'm sorry if I miss something... > > This curr is curr == memcg = mem_cgroup_from_css(css) <= already try_get() done. > double refcounted ? Yes we get 2 references here. One for the returned memcg - which will be released either by mem_cgroup_iter_break or a next iteration round (where it would be prev) and the other is for last_visited which is released when a new memcg is cached. [...] -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>