aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c69
-rw-r--r--mm/oom_kill.c1
2 files changed, 70 insertions, 0 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 025f8abfae2d..2bdb6149faeb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -27,6 +27,7 @@
27#include <linux/backing-dev.h> 27#include <linux/backing-dev.h>
28#include <linux/bit_spinlock.h> 28#include <linux/bit_spinlock.h>
29#include <linux/rcupdate.h> 29#include <linux/rcupdate.h>
30#include <linux/limits.h>
30#include <linux/mutex.h> 31#include <linux/mutex.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/swap.h> 33#include <linux/swap.h>
@@ -721,6 +722,74 @@ static int mem_cgroup_count_children_cb(struct mem_cgroup *mem, void *data)
721 (*val)++; 722 (*val)++;
722 return 0; 723 return 0;
723} 724}
725
726/**
727 * mem_cgroup_print_mem_info: Called from OOM with tasklist_lock held in read mode.
728 * @memcg: The memory cgroup that went over limit
729 * @p: Task that is going to be killed
730 *
731 * NOTE: @memcg and @p's mem_cgroup can be different when hierarchy is
732 * enabled
733 */
734void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
735{
736 struct cgroup *task_cgrp;
737 struct cgroup *mem_cgrp;
738 /*
739 * Need a buffer in BSS, can't rely on allocations. The code relies
740 * on the assumption that OOM is serialized for memory controller.
741 * If this assumption is broken, revisit this code.
742 */
743 static char memcg_name[PATH_MAX];
744 int ret;
745
746 if (!memcg)
747 return;
748
749
750 rcu_read_lock();
751
752 mem_cgrp = memcg->css.cgroup;
753 task_cgrp = task_cgroup(p, mem_cgroup_subsys_id);
754
755 ret = cgroup_path(task_cgrp, memcg_name, PATH_MAX);
756 if (ret < 0) {
757 /*
758 * Unfortunately, we are unable to convert to a useful name
759 * But we'll still print out the usage information
760 */
761 rcu_read_unlock();
762 goto done;
763 }
764 rcu_read_unlock();
765
766 printk(KERN_INFO "Task in %s killed", memcg_name);
767
768 rcu_read_lock();
769 ret = cgroup_path(mem_cgrp, memcg_name, PATH_MAX);
770 if (ret < 0) {
771 rcu_read_unlock();
772 goto done;
773 }
774 rcu_read_unlock();
775
776 /*
777 * Continues from above, so we don't need an KERN_ level
778 */
779 printk(KERN_CONT " as a result of limit of %s\n", memcg_name);
780done:
781
782 printk(KERN_INFO "memory: usage %llukB, limit %llukB, failcnt %llu\n",
783 res_counter_read_u64(&memcg->res, RES_USAGE) >> 10,
784 res_counter_read_u64(&memcg->res, RES_LIMIT) >> 10,
785 res_counter_read_u64(&memcg->res, RES_FAILCNT));
786 printk(KERN_INFO "memory+swap: usage %llukB, limit %llukB, "
787 "failcnt %llu\n",
788 res_counter_read_u64(&memcg->memsw, RES_USAGE) >> 10,
789 res_counter_read_u64(&memcg->memsw, RES_LIMIT) >> 10,
790 res_counter_read_u64(&memcg->memsw, RES_FAILCNT));
791}
792
724/* 793/*
725 * This function returns the number of memcg under hierarchy tree. Returns 794 * This function returns the number of memcg under hierarchy tree. Returns
726 * 1(self count) if no children. 795 * 1(self count) if no children.
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index d3b9bac085b5..2f3166e308d9 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -394,6 +394,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
394 cpuset_print_task_mems_allowed(current); 394 cpuset_print_task_mems_allowed(current);
395 task_unlock(current); 395 task_unlock(current);
396 dump_stack(); 396 dump_stack();
397 mem_cgroup_print_oom_info(mem, current);
397 show_mem(); 398 show_mem();
398 if (sysctl_oom_dump_tasks) 399 if (sysctl_oom_dump_tasks)
399 dump_tasks(mem); 400 dump_tasks(mem);