aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index da07784dde87..98f80beeac7f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1117,14 +1117,22 @@ skip_node:
1117 * skipped and we should continue the tree walk. 1117 * skipped and we should continue the tree walk.
1118 * last_visited css is safe to use because it is 1118 * last_visited css is safe to use because it is
1119 * protected by css_get and the tree walk is rcu safe. 1119 * protected by css_get and the tree walk is rcu safe.
1120 *
1121 * We do not take a reference on the root of the tree walk
1122 * because we might race with the root removal when it would
1123 * be the only node in the iterated hierarchy and mem_cgroup_iter
1124 * would end up in an endless loop because it expects that at
1125 * least one valid node will be returned. Root cannot disappear
1126 * because caller of the iterator should hold it already so
1127 * skipping css reference should be safe.
1120 */ 1128 */
1121 if (next_css) { 1129 if (next_css) {
1122 if ((next_css->flags & CSS_ONLINE) && css_tryget(next_css)) 1130 if ((next_css->flags & CSS_ONLINE) &&
1131 (next_css == &root->css || css_tryget(next_css)))
1123 return mem_cgroup_from_css(next_css); 1132 return mem_cgroup_from_css(next_css);
1124 else { 1133
1125 prev_css = next_css; 1134 prev_css = next_css;
1126 goto skip_node; 1135 goto skip_node;
1127 }
1128 } 1136 }
1129 1137
1130 return NULL; 1138 return NULL;