Merge tag 'for-linus-5.1b-rc1b-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / mm / oom_kill.c
index 26ea863..3a24848 100644 (file)
@@ -843,7 +843,7 @@ static bool task_will_free_mem(struct task_struct *task)
        return ret;
 }
 
-static void __oom_kill_process(struct task_struct *victim)
+static void __oom_kill_process(struct task_struct *victim, const char *message)
 {
        struct task_struct *p;
        struct mm_struct *mm;
@@ -874,8 +874,9 @@ static void __oom_kill_process(struct task_struct *victim)
         */
        do_send_sig_info(SIGKILL, SEND_SIG_PRIV, victim, PIDTYPE_TGID);
        mark_oom_victim(victim);
-       pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
-               task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
+       pr_err("%s: Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
+               message, task_pid_nr(victim), victim->comm,
+               K(victim->mm->total_vm),
                K(get_mm_counter(victim->mm, MM_ANONPAGES)),
                K(get_mm_counter(victim->mm, MM_FILEPAGES)),
                K(get_mm_counter(victim->mm, MM_SHMEMPAGES)));
@@ -926,24 +927,20 @@ static void __oom_kill_process(struct task_struct *victim)
  * Kill provided task unless it's secured by setting
  * oom_score_adj to OOM_SCORE_ADJ_MIN.
  */
-static int oom_kill_memcg_member(struct task_struct *task, void *unused)
+static int oom_kill_memcg_member(struct task_struct *task, void *message)
 {
-       if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
+       if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN &&
+           !is_global_init(task)) {
                get_task_struct(task);
-               __oom_kill_process(task);
+               __oom_kill_process(task, message);
        }
        return 0;
 }
 
 static void oom_kill_process(struct oom_control *oc, const char *message)
 {
-       struct task_struct *p = oc->chosen;
-       unsigned int points = oc->chosen_points;
-       struct task_struct *victim = p;
-       struct task_struct *child;
-       struct task_struct *t;
+       struct task_struct *victim = oc->chosen;
        struct mem_cgroup *oom_group;
-       unsigned int victim_points = 0;
        static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
                                              DEFAULT_RATELIMIT_BURST);
 
@@ -952,57 +949,18 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
         * its children or threads, just give it access to memory reserves
         * so it can die quickly
         */
-       task_lock(p);
-       if (task_will_free_mem(p)) {
-               mark_oom_victim(p);
-               wake_oom_reaper(p);
-               task_unlock(p);
-               put_task_struct(p);
+       task_lock(victim);
+       if (task_will_free_mem(victim)) {
+               mark_oom_victim(victim);
+               wake_oom_reaper(victim);
+               task_unlock(victim);
+               put_task_struct(victim);
                return;
        }
-       task_unlock(p);
+       task_unlock(victim);
 
        if (__ratelimit(&oom_rs))
-               dump_header(oc, p);
-
-       pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
-               message, task_pid_nr(p), p->comm, points);
-
-       /*
-        * If any of p's children has a different mm and is eligible for kill,
-        * the one with the highest oom_badness() score is sacrificed for its
-        * parent.  This attempts to lose the minimal amount of work done while
-        * still freeing memory.
-        */
-       read_lock(&tasklist_lock);
-
-       /*
-        * The task 'p' might have already exited before reaching here. The
-        * put_task_struct() will free task_struct 'p' while the loop still try
-        * to access the field of 'p', so, get an extra reference.
-        */
-       get_task_struct(p);
-       for_each_thread(p, t) {
-               list_for_each_entry(child, &t->children, sibling) {
-                       unsigned int child_points;
-
-                       if (process_shares_mm(child, p->mm))
-                               continue;
-                       /*
-                        * oom_badness() returns 0 if the thread is unkillable
-                        */
-                       child_points = oom_badness(child,
-                               oc->memcg, oc->nodemask, oc->totalpages);
-                       if (child_points > victim_points) {
-                               put_task_struct(victim);
-                               victim = child;
-                               victim_points = child_points;
-                               get_task_struct(victim);
-                       }
-               }
-       }
-       put_task_struct(p);
-       read_unlock(&tasklist_lock);
+               dump_header(oc, victim);
 
        /*
         * Do we need to kill the entire memory cgroup?
@@ -1011,14 +969,15 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
         */
        oom_group = mem_cgroup_get_oom_group(victim, oc->memcg);
 
-       __oom_kill_process(victim);
+       __oom_kill_process(victim, message);
 
        /*
         * If necessary, kill all tasks in the selected memory cgroup.
         */
        if (oom_group) {
                mem_cgroup_print_oom_group(oom_group);
-               mem_cgroup_scan_tasks(oom_group, oom_kill_memcg_member, NULL);
+               mem_cgroup_scan_tasks(oom_group, oom_kill_memcg_member,
+                                     (void*)message);
                mem_cgroup_put(oom_group);
        }
 }