aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4f73c823c59f..b78972e2f43f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1453,7 +1453,7 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg)
1453/* 1453/*
1454 * Return the memory (and swap, if configured) limit for a memcg. 1454 * Return the memory (and swap, if configured) limit for a memcg.
1455 */ 1455 */
1456u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) 1456static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
1457{ 1457{
1458 u64 limit; 1458 u64 limit;
1459 u64 memsw; 1459 u64 memsw;
@@ -1469,6 +1469,65 @@ u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
1469 return min(limit, memsw); 1469 return min(limit, memsw);
1470} 1470}
1471 1471
1472void __mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
1473 int order)
1474{
1475 struct mem_cgroup *iter;
1476 unsigned long chosen_points = 0;
1477 unsigned long totalpages;
1478 unsigned int points = 0;
1479 struct task_struct *chosen = NULL;
1480
1481 totalpages = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1;
1482 for_each_mem_cgroup_tree(iter, memcg) {
1483 struct cgroup *cgroup = iter->css.cgroup;
1484 struct cgroup_iter it;
1485 struct task_struct *task;
1486
1487 cgroup_iter_start(cgroup, &it);
1488 while ((task = cgroup_iter_next(cgroup, &it))) {
1489 switch (oom_scan_process_thread(task, totalpages, NULL,
1490 false)) {
1491 case OOM_SCAN_SELECT:
1492 if (chosen)
1493 put_task_struct(chosen);
1494 chosen = task;
1495 chosen_points = ULONG_MAX;
1496 get_task_struct(chosen);
1497 /* fall through */
1498 case OOM_SCAN_CONTINUE:
1499 continue;
1500 case OOM_SCAN_ABORT:
1501 cgroup_iter_end(cgroup, &it);
1502 mem_cgroup_iter_break(memcg, iter);
1503 if (chosen)
1504 put_task_struct(chosen);
1505 return;
1506 case OOM_SCAN_OK:
1507 break;
1508 };
1509 points = oom_badness(task, memcg, NULL, totalpages);
1510 if (points > chosen_points) {
1511 if (chosen)
1512 put_task_struct(chosen);
1513 chosen = task;
1514 chosen_points = points;
1515 get_task_struct(chosen);
1516 }
1517 }
1518 cgroup_iter_end(cgroup, &it);
1519 }
1520
1521 if (!chosen)
1522 return;
1523 points = chosen_points * 1000 / totalpages;
1524 read_lock(&tasklist_lock);
1525 oom_kill_process(chosen, gfp_mask, order, points, totalpages, memcg,
1526 NULL, "Memory cgroup out of memory");
1527 read_unlock(&tasklist_lock);
1528 put_task_struct(chosen);
1529}
1530
1472static unsigned long mem_cgroup_reclaim(struct mem_cgroup *memcg, 1531static unsigned long mem_cgroup_reclaim(struct mem_cgroup *memcg,
1473 gfp_t gfp_mask, 1532 gfp_t gfp_mask,
1474 unsigned long flags) 1533 unsigned long flags)