Merge remote branch 'linus/master'
[powerpc.git] / mm / oom_kill.c
index 64751dc..4194b9d 100644 (file)
@@ -29,6 +29,7 @@
 
 int sysctl_panic_on_oom;
 int sysctl_oom_kill_allocating_task;
+int sysctl_oom_dump_tasks;
 static DEFINE_SPINLOCK(zone_scan_mutex);
 /* #define DEBUG */
 
@@ -65,13 +66,6 @@ unsigned long badness(struct task_struct *p, unsigned long uptime,
                return 0;
        }
 
-#ifdef CONFIG_CGROUP_MEM_CONT
-       if (mem != NULL && mm->mem_cgroup != mem) {
-               task_unlock(p);
-               return 0;
-       }
-#endif
-
        /*
         * The memory size of the process is the basis for the badness.
         */
@@ -223,6 +217,8 @@ static struct task_struct *select_bad_process(unsigned long *ppoints,
                /* skip the init task */
                if (is_global_init(p))
                        continue;
+               if (mem && !task_in_mem_cgroup(p, mem))
+                       continue;
 
                /*
                 * This task already has access to memory reserves and is
@@ -267,6 +263,41 @@ static struct task_struct *select_bad_process(unsigned long *ppoints,
        return chosen;
 }
 
+/**
+ * Dumps the current memory state of all system tasks, excluding kernel threads.
+ * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj
+ * score, and name.
+ *
+ * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are
+ * shown.
+ *
+ * Call with tasklist_lock read-locked.
+ */
+static void dump_tasks(const struct mem_cgroup *mem)
+{
+       struct task_struct *g, *p;
+
+       printk(KERN_INFO "[ pid ]   uid  tgid total_vm      rss cpu oom_adj "
+              "name\n");
+       do_each_thread(g, p) {
+               /*
+                * total_vm and rss sizes do not exist for tasks with a
+                * detached mm so there's no need to report them.
+                */
+               if (!p->mm)
+                       continue;
+               if (mem && !task_in_mem_cgroup(p, mem))
+                       continue;
+
+               task_lock(p);
+               printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d     %3d %s\n",
+                      p->pid, p->uid, p->tgid, p->mm->total_vm,
+                      get_mm_rss(p->mm), (int)task_cpu(p), p->oomkilladj,
+                      p->comm);
+               task_unlock(p);
+       } while_each_thread(g, p);
+}
+
 /**
  * Send SIGKILL to the selected  process irrespective of  CAP_SYS_RAW_IO
  * flag though it's unlikely that  we select a process with CAP_SYS_RAW_IO
@@ -344,7 +375,8 @@ static int oom_kill_task(struct task_struct *p)
 }
 
 static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
-                           unsigned long points, const char *message)
+                           unsigned long points, struct mem_cgroup *mem,
+                           const char *message)
 {
        struct task_struct *c;
 
@@ -354,6 +386,8 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
                        current->comm, gfp_mask, order, current->oomkilladj);
                dump_stack();
                show_mem();
+               if (sysctl_oom_dump_tasks)
+                       dump_tasks(mem);
        }
 
        /*
@@ -394,7 +428,7 @@ retry:
        if (!p)
                p = current;
 
-       if (oom_kill_process(p, gfp_mask, 0, points,
+       if (oom_kill_process(p, gfp_mask, 0, points, mem,
                                "Memory cgroup out of memory"))
                goto retry;
 out:
@@ -500,7 +534,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
 
        switch (constraint) {
        case CONSTRAINT_MEMORY_POLICY:
-               oom_kill_process(current, gfp_mask, order, points,
+               oom_kill_process(current, gfp_mask, order, points, NULL,
                                "No available memory (MPOL_BIND)");
                break;
 
@@ -510,7 +544,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
                /* Fall-through */
        case CONSTRAINT_CPUSET:
                if (sysctl_oom_kill_allocating_task) {
-                       oom_kill_process(current, gfp_mask, order, points,
+                       oom_kill_process(current, gfp_mask, order, points, NULL,
                                        "Out of memory (oom_kill_allocating_task)");
                        break;
                }
@@ -530,7 +564,7 @@ retry:
                        panic("Out of memory and no killable processes...\n");
                }
 
-               if (oom_kill_process(p, gfp_mask, order, points,
+               if (oom_kill_process(p, gfp_mask, order, points, NULL,
                                     "Out of memory"))
                        goto retry;