aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2012-11-16 17:14:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-11-16 17:33:04 -0500
commit9a5a8f19b43430752067ecaee62fc59e11e88fa6 (patch)
treeffa31761b0e208d8be324dc97368caf4bea87fd8
parent1756954c61cb5c97c618ccb366482b9c1f891d6d (diff)
memcg: oom: fix totalpages calculation for memory.swappiness==0
oom_badness() takes a totalpages argument which says how many pages are available and it uses it as a base for the score calculation. The value is calculated by mem_cgroup_get_limit which considers both limit and total_swap_pages (resp. memsw portion of it). This is usually correct but since fe35004fbf9e ("mm: avoid swapping out with swappiness==0") we do not swap when swappiness is 0 which means that we cannot really use up all the totalpages pages. This in turn confuses oom score calculation if the memcg limit is much smaller than the available swap because the used memory (capped by the limit) is negligible comparing to totalpages so the resulting score is too small if adj!=0 (typically task with CAP_SYS_ADMIN or non zero oom_score_adj). A wrong process might be selected as result. The problem can be worked around by checking mem_cgroup_swappiness==0 and not considering swap at all in such a case. Signed-off-by: Michal Hocko <mhocko@suse.cz> Acked-by: David Rientjes <rientjes@google.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/cgroups/memory.txt4
-rw-r--r--mm/memcontrol.c21
2 files changed, 19 insertions, 6 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index c07f7b4fb88d..71c4da413444 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -466,6 +466,10 @@ Note:
4665.3 swappiness 4665.3 swappiness
467 467
468Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. 468Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
469Please note that unlike the global swappiness, memcg knob set to 0
470really prevents from any swapping even if there is a swap storage
471available. This might lead to memcg OOM killer if there are no file
472pages to reclaim.
469 473
470Following cgroups' swappiness can't be changed. 474Following cgroups' swappiness can't be changed.
471- root cgroup (uses /proc/sys/vm/swappiness). 475- root cgroup (uses /proc/sys/vm/swappiness).
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 7acf43bf04a2..93a7e36ded89 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1452,17 +1452,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg)
1452static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) 1452static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
1453{ 1453{
1454 u64 limit; 1454 u64 limit;
1455 u64 memsw;
1456 1455
1457 limit = res_counter_read_u64(&memcg->res, RES_LIMIT); 1456 limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
1458 limit += total_swap_pages << PAGE_SHIFT;
1459 1457
1460 memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
1461 /* 1458 /*
1462 * If memsw is finite and limits the amount of swap space available 1459 * Do not consider swap space if we cannot swap due to swappiness
1463 * to this memcg, return that limit.
1464 */ 1460 */
1465 return min(limit, memsw); 1461 if (mem_cgroup_swappiness(memcg)) {
1462 u64 memsw;
1463
1464 limit += total_swap_pages << PAGE_SHIFT;
1465 memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
1466
1467 /*
1468 * If memsw is finite and limits the amount of swap space
1469 * available to this memcg, return that limit.
1470 */
1471 limit = min(limit, memsw);
1472 }
1473
1474 return limit;
1466} 1475}
1467 1476
1468void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, 1477void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,