aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2014-12-10 18:44:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 20:41:08 -0500
commit2314b42db67be30b747122d65c6cd2c85da34538 (patch)
tree5dffdf758736c83b6bfe8b6ada0dbb99d992c0f5 /mm
parent413918bb61b4fa027baa3e79546c47f15e4b9ea8 (diff)
mm: memcontrol: drop bogus RCU locking from mem_cgroup_same_or_subtree()
None of the mem_cgroup_same_or_subtree() callers actually require it to take the RCU lock, either because they hold it themselves or they have css references. Remove it. To make the API change clear, rename the leftover helper to mem_cgroup_is_descendant() to match cgroup_is_descendant(). Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Vladimir Davydov <vdavydov@parallels.com> Acked-by: Michal Hocko <mhocko@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c59
-rw-r--r--mm/oom_kill.c4
2 files changed, 18 insertions, 45 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e5dcebd71dfb..b841bf430179 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1328,41 +1328,24 @@ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
1328 VM_BUG_ON((long)(*lru_size) < 0); 1328 VM_BUG_ON((long)(*lru_size) < 0);
1329} 1329}
1330 1330
1331/* 1331bool mem_cgroup_is_descendant(struct mem_cgroup *memcg, struct mem_cgroup *root)
1332 * Checks whether given mem is same or in the root_mem_cgroup's
1333 * hierarchy subtree
1334 */
1335bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
1336 struct mem_cgroup *memcg)
1337{ 1332{
1338 if (root_memcg == memcg) 1333 if (root == memcg)
1339 return true; 1334 return true;
1340 if (!root_memcg->use_hierarchy) 1335 if (!root->use_hierarchy)
1341 return false; 1336 return false;
1342 return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup); 1337 return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
1343}
1344
1345static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
1346 struct mem_cgroup *memcg)
1347{
1348 bool ret;
1349
1350 rcu_read_lock();
1351 ret = __mem_cgroup_same_or_subtree(root_memcg, memcg);
1352 rcu_read_unlock();
1353 return ret;
1354} 1338}
1355 1339
1356bool task_in_mem_cgroup(struct task_struct *task, 1340bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg)
1357 const struct mem_cgroup *memcg)
1358{ 1341{
1359 struct mem_cgroup *curr; 1342 struct mem_cgroup *task_memcg;
1360 struct task_struct *p; 1343 struct task_struct *p;
1361 bool ret; 1344 bool ret;
1362 1345
1363 p = find_lock_task_mm(task); 1346 p = find_lock_task_mm(task);
1364 if (p) { 1347 if (p) {
1365 curr = get_mem_cgroup_from_mm(p->mm); 1348 task_memcg = get_mem_cgroup_from_mm(p->mm);
1366 task_unlock(p); 1349 task_unlock(p);
1367 } else { 1350 } else {
1368 /* 1351 /*
@@ -1371,18 +1354,12 @@ bool task_in_mem_cgroup(struct task_struct *task,
1371 * killed to prevent needlessly killing additional tasks. 1354 * killed to prevent needlessly killing additional tasks.
1372 */ 1355 */
1373 rcu_read_lock(); 1356 rcu_read_lock();
1374 curr = mem_cgroup_from_task(task); 1357 task_memcg = mem_cgroup_from_task(task);
1375 css_get(&curr->css); 1358 css_get(&task_memcg->css);
1376 rcu_read_unlock(); 1359 rcu_read_unlock();
1377 } 1360 }
1378 /* 1361 ret = mem_cgroup_is_descendant(task_memcg, memcg);
1379 * We should check use_hierarchy of "memcg" not "curr". Because checking 1362 css_put(&task_memcg->css);
1380 * use_hierarchy of "curr" here make this function true if hierarchy is
1381 * enabled in "curr" and "curr" is a child of "memcg" in *cgroup*
1382 * hierarchy(even if use_hierarchy is disabled in "memcg").
1383 */
1384 ret = mem_cgroup_same_or_subtree(memcg, curr);
1385 css_put(&curr->css);
1386 return ret; 1363 return ret;
1387} 1364}
1388 1365
@@ -1467,8 +1444,8 @@ static bool mem_cgroup_under_move(struct mem_cgroup *memcg)
1467 if (!from) 1444 if (!from)
1468 goto unlock; 1445 goto unlock;
1469 1446
1470 ret = mem_cgroup_same_or_subtree(memcg, from) 1447 ret = mem_cgroup_is_descendant(from, memcg) ||
1471 || mem_cgroup_same_or_subtree(memcg, to); 1448 mem_cgroup_is_descendant(to, memcg);
1472unlock: 1449unlock:
1473 spin_unlock(&mc.lock); 1450 spin_unlock(&mc.lock);
1474 return ret; 1451 return ret;
@@ -1900,12 +1877,8 @@ static int memcg_oom_wake_function(wait_queue_t *wait,
1900 oom_wait_info = container_of(wait, struct oom_wait_info, wait); 1877 oom_wait_info = container_of(wait, struct oom_wait_info, wait);
1901 oom_wait_memcg = oom_wait_info->memcg; 1878 oom_wait_memcg = oom_wait_info->memcg;
1902 1879
1903 /* 1880 if (!mem_cgroup_is_descendant(wake_memcg, oom_wait_memcg) &&
1904 * Both of oom_wait_info->memcg and wake_memcg are stable under us. 1881 !mem_cgroup_is_descendant(oom_wait_memcg, wake_memcg))
1905 * Then we can use css_is_ancestor without taking care of RCU.
1906 */
1907 if (!mem_cgroup_same_or_subtree(oom_wait_memcg, wake_memcg)
1908 && !mem_cgroup_same_or_subtree(wake_memcg, oom_wait_memcg))
1909 return 0; 1882 return 0;
1910 return autoremove_wake_function(wait, mode, sync, arg); 1883 return autoremove_wake_function(wait, mode, sync, arg);
1911} 1884}
@@ -2225,7 +2198,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)
2225 memcg = stock->cached; 2198 memcg = stock->cached;
2226 if (!memcg || !stock->nr_pages) 2199 if (!memcg || !stock->nr_pages)
2227 continue; 2200 continue;
2228 if (!mem_cgroup_same_or_subtree(root_memcg, memcg)) 2201 if (!mem_cgroup_is_descendant(memcg, root_memcg))
2229 continue; 2202 continue;
2230 if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) { 2203 if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) {
2231 if (cpu == curcpu) 2204 if (cpu == curcpu)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 5340f6b91312..3b014d326151 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -119,7 +119,7 @@ found:
119 119
120/* return true if the task is not adequate as candidate victim task. */ 120/* return true if the task is not adequate as candidate victim task. */
121static bool oom_unkillable_task(struct task_struct *p, 121static bool oom_unkillable_task(struct task_struct *p,
122 const struct mem_cgroup *memcg, const nodemask_t *nodemask) 122 struct mem_cgroup *memcg, const nodemask_t *nodemask)
123{ 123{
124 if (is_global_init(p)) 124 if (is_global_init(p))
125 return true; 125 return true;
@@ -353,7 +353,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
353 * State information includes task's pid, uid, tgid, vm size, rss, nr_ptes, 353 * State information includes task's pid, uid, tgid, vm size, rss, nr_ptes,
354 * swapents, oom_score_adj value, and name. 354 * swapents, oom_score_adj value, and name.
355 */ 355 */
356static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemask) 356static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
357{ 357{
358 struct task_struct *p; 358 struct task_struct *p;
359 struct task_struct *task; 359 struct task_struct *task;