aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2011-07-26 19:08:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 19:49:43 -0400
commit3e92041d68b40c47faa34c7dc08fc650a6c36adc (patch)
tree29eab5bcd1bbf333cb25ed140a245645f9d7e0c4 /mm/memcontrol.c
parentd38144b7a5f8d0a5e05d549177191374c6911009 (diff)
memcg: add mem_cgroup_same_or_subtree() helper
We are checking whether a given two groups are same or at least in the same subtree of a hierarchy at several places. Let's make a helper for it to make code easier to read. Signed-off-by: Michal Hocko <mhocko@suse.cz> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Balbir Singh <bsingharora@gmail.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.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index af920d0f9025..79f23a189941 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1108,6 +1108,21 @@ void mem_cgroup_move_lists(struct page *page,
1108 mem_cgroup_add_lru_list(page, to); 1108 mem_cgroup_add_lru_list(page, to);
1109} 1109}
1110 1110
1111/*
1112 * Checks whether given mem is same or in the root_mem's
1113 * hierarchy subtree
1114 */
1115static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_mem,
1116 struct mem_cgroup *mem)
1117{
1118 if (root_mem != mem) {
1119 return (root_mem->use_hierarchy &&
1120 css_is_ancestor(&mem->css, &root_mem->css));
1121 }
1122
1123 return true;
1124}
1125
1111int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) 1126int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
1112{ 1127{
1113 int ret; 1128 int ret;
@@ -1127,10 +1142,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
1127 * enabled in "curr" and "curr" is a child of "mem" in *cgroup* 1142 * enabled in "curr" and "curr" is a child of "mem" in *cgroup*
1128 * hierarchy(even if use_hierarchy is disabled in "mem"). 1143 * hierarchy(even if use_hierarchy is disabled in "mem").
1129 */ 1144 */
1130 if (mem->use_hierarchy) 1145 ret = mem_cgroup_same_or_subtree(mem, curr);
1131 ret = css_is_ancestor(&curr->css, &mem->css);
1132 else
1133 ret = (curr == mem);
1134 css_put(&curr->css); 1146 css_put(&curr->css);
1135 return ret; 1147 return ret;
1136} 1148}
@@ -1369,10 +1381,9 @@ static bool mem_cgroup_under_move(struct mem_cgroup *mem)
1369 to = mc.to; 1381 to = mc.to;
1370 if (!from) 1382 if (!from)
1371 goto unlock; 1383 goto unlock;
1372 if (from == mem || to == mem 1384
1373 || (mem->use_hierarchy && css_is_ancestor(&from->css, &mem->css)) 1385 ret = mem_cgroup_same_or_subtree(mem, from)
1374 || (mem->use_hierarchy && css_is_ancestor(&to->css, &mem->css))) 1386 || mem_cgroup_same_or_subtree(mem, to);
1375 ret = true;
1376unlock: 1387unlock:
1377 spin_unlock(&mc.lock); 1388 spin_unlock(&mc.lock);
1378 return ret; 1389 return ret;
@@ -1915,25 +1926,20 @@ struct oom_wait_info {
1915static int memcg_oom_wake_function(wait_queue_t *wait, 1926static int memcg_oom_wake_function(wait_queue_t *wait,
1916 unsigned mode, int sync, void *arg) 1927 unsigned mode, int sync, void *arg)
1917{ 1928{
1918 struct mem_cgroup *wake_mem = (struct mem_cgroup *)arg; 1929 struct mem_cgroup *wake_mem = (struct mem_cgroup *)arg,
1930 *oom_wait_mem;
1919 struct oom_wait_info *oom_wait_info; 1931 struct oom_wait_info *oom_wait_info;
1920 1932
1921 oom_wait_info = container_of(wait, struct oom_wait_info, wait); 1933 oom_wait_info = container_of(wait, struct oom_wait_info, wait);
1934 oom_wait_mem = oom_wait_info->mem;
1922 1935
1923 if (oom_wait_info->mem == wake_mem)
1924 goto wakeup;
1925 /* if no hierarchy, no match */
1926 if (!oom_wait_info->mem->use_hierarchy || !wake_mem->use_hierarchy)
1927 return 0;
1928 /* 1936 /*
1929 * Both of oom_wait_info->mem and wake_mem are stable under us. 1937 * Both of oom_wait_info->mem and wake_mem are stable under us.
1930 * Then we can use css_is_ancestor without taking care of RCU. 1938 * Then we can use css_is_ancestor without taking care of RCU.
1931 */ 1939 */
1932 if (!css_is_ancestor(&oom_wait_info->mem->css, &wake_mem->css) && 1940 if (!mem_cgroup_same_or_subtree(oom_wait_mem, wake_mem)
1933 !css_is_ancestor(&wake_mem->css, &oom_wait_info->mem->css)) 1941 && !mem_cgroup_same_or_subtree(wake_mem, oom_wait_mem))
1934 return 0; 1942 return 0;
1935
1936wakeup:
1937 return autoremove_wake_function(wait, mode, sync, arg); 1943 return autoremove_wake_function(wait, mode, sync, arg);
1938} 1944}
1939 1945
@@ -2178,13 +2184,8 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync)
2178 mem = stock->cached; 2184 mem = stock->cached;
2179 if (!mem || !stock->nr_pages) 2185 if (!mem || !stock->nr_pages)
2180 continue; 2186 continue;
2181 if (mem != root_mem) { 2187 if (!mem_cgroup_same_or_subtree(root_mem, mem))
2182 if (!root_mem->use_hierarchy) 2188 continue;
2183 continue;
2184 /* check whether "mem" is under tree of "root_mem" */
2185 if (!css_is_ancestor(&mem->css, &root_mem->css))
2186 continue;
2187 }
2188 if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) { 2189 if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) {
2189 if (cpu == curcpu) 2190 if (cpu == curcpu)
2190 drain_local_stock(&stock->work); 2191 drain_local_stock(&stock->work);