diff options
author | Michal Hocko <mhocko@suse.cz> | 2013-04-29 18:07:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 18:54:33 -0400 |
commit | 16248d8fe65ea116cc30b915e05a1c29496da120 (patch) | |
tree | 02c885d8aac98b937681d442a8cf0167e062f540 /mm/memcontrol.c | |
parent | 19f39402864ea3935b36ab1066c6283d6ea53f44 (diff) |
memcg: further simplify mem_cgroup_iter
mem_cgroup_iter basically does two things currently. It takes care of
the house keeping (reference counting, raclaim cookie) and it iterates
through a hierarchy tree (by using cgroup generic tree walk). The code
would be much more easier to follow if we move the iteration outside of
the function (to __mem_cgrou_iter_next) so the distinction is more
clear. This patch doesn't introduce any functional changes.
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/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 614d0d9c0deb..2bdac3ececd0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1073,6 +1073,51 @@ struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) | |||
1073 | return memcg; | 1073 | return memcg; |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | /* | ||
1077 | * Returns a next (in a pre-order walk) alive memcg (with elevated css | ||
1078 | * ref. count) or NULL if the whole root's subtree has been visited. | ||
1079 | * | ||
1080 | * helper function to be used by mem_cgroup_iter | ||
1081 | */ | ||
1082 | static struct mem_cgroup *__mem_cgroup_iter_next(struct mem_cgroup *root, | ||
1083 | struct mem_cgroup *last_visited) | ||
1084 | { | ||
1085 | struct cgroup *prev_cgroup, *next_cgroup; | ||
1086 | |||
1087 | /* | ||
1088 | * Root is not visited by cgroup iterators so it needs an | ||
1089 | * explicit visit. | ||
1090 | */ | ||
1091 | if (!last_visited) | ||
1092 | return root; | ||
1093 | |||
1094 | prev_cgroup = (last_visited == root) ? NULL | ||
1095 | : last_visited->css.cgroup; | ||
1096 | skip_node: | ||
1097 | next_cgroup = cgroup_next_descendant_pre( | ||
1098 | prev_cgroup, root->css.cgroup); | ||
1099 | |||
1100 | /* | ||
1101 | * Even if we found a group we have to make sure it is | ||
1102 | * alive. css && !memcg means that the groups should be | ||
1103 | * skipped and we should continue the tree walk. | ||
1104 | * last_visited css is safe to use because it is | ||
1105 | * protected by css_get and the tree walk is rcu safe. | ||
1106 | */ | ||
1107 | if (next_cgroup) { | ||
1108 | struct mem_cgroup *mem = mem_cgroup_from_cont( | ||
1109 | next_cgroup); | ||
1110 | if (css_tryget(&mem->css)) | ||
1111 | return mem; | ||
1112 | else { | ||
1113 | prev_cgroup = next_cgroup; | ||
1114 | goto skip_node; | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | return NULL; | ||
1119 | } | ||
1120 | |||
1076 | /** | 1121 | /** |
1077 | * mem_cgroup_iter - iterate over memory cgroup hierarchy | 1122 | * mem_cgroup_iter - iterate over memory cgroup hierarchy |
1078 | * @root: hierarchy root | 1123 | * @root: hierarchy root |
@@ -1153,39 +1198,7 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, | |||
1153 | } | 1198 | } |
1154 | } | 1199 | } |
1155 | 1200 | ||
1156 | /* | 1201 | memcg = __mem_cgroup_iter_next(root, last_visited); |
1157 | * Root is not visited by cgroup iterators so it needs an | ||
1158 | * explicit visit. | ||
1159 | */ | ||
1160 | if (!last_visited) { | ||
1161 | memcg = root; | ||
1162 | } else { | ||
1163 | struct cgroup *prev_cgroup, *next_cgroup; | ||
1164 | |||
1165 | prev_cgroup = (last_visited == root) ? NULL | ||
1166 | : last_visited->css.cgroup; | ||
1167 | skip_node: | ||
1168 | next_cgroup = cgroup_next_descendant_pre( | ||
1169 | prev_cgroup, root->css.cgroup); | ||
1170 | |||
1171 | /* | ||
1172 | * Even if we found a group we have to make sure it is | ||
1173 | * alive. css && !memcg means that the groups should be | ||
1174 | * skipped and we should continue the tree walk. | ||
1175 | * last_visited css is safe to use because it is | ||
1176 | * protected by css_get and the tree walk is rcu safe. | ||
1177 | */ | ||
1178 | if (next_cgroup) { | ||
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 | } | ||
1189 | 1202 | ||
1190 | if (reclaim) { | 1203 | if (reclaim) { |
1191 | if (last_visited) | 1204 | if (last_visited) |