Merge branch 'x86/trampoline' into x86/urgent
[pandora-kernel.git] / mm / oom_kill.c
index 9f09a1f..ed0e196 100644 (file)
@@ -180,10 +180,10 @@ static bool oom_unkillable_task(struct task_struct *p,
  * predictable as possible.  The goal is to return the highest value for the
  * task consuming the most memory to avoid subsequent oom failures.
  */
-unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
-                     const nodemask_t *nodemask, unsigned long totalpages)
+unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
+                         const nodemask_t *nodemask, unsigned long totalpages)
 {
-       long points;
+       unsigned long points;
 
        if (oom_unkillable_task(p, memcg, nodemask))
                return 0;
@@ -197,22 +197,12 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
                return 0;
        }
 
-       /*
-        * The memory controller may have a limit of 0 bytes, so avoid a divide
-        * by zero, if necessary.
-        */
-       if (!totalpages)
-               totalpages = 1;
-
        /*
         * The baseline for the badness score is the proportion of RAM that each
         * task's rss, pagetable and swap space use.
         */
-       points = get_mm_rss(p->mm) + p->mm->nr_ptes;
-       points += get_mm_counter(p->mm, MM_SWAPENTS);
-
-       points *= 1000;
-       points /= totalpages;
+       points = get_mm_rss(p->mm) + p->mm->nr_ptes +
+                get_mm_counter(p->mm, MM_SWAPENTS);
        task_unlock(p);
 
        /*
@@ -220,23 +210,20 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
         * implementation used by LSMs.
         */
        if (has_capability_noaudit(p, CAP_SYS_ADMIN))
-               points -= 30;
+               points -= 30 * totalpages / 1000;
 
        /*
         * /proc/pid/oom_score_adj ranges from -1000 to +1000 such that it may
         * either completely disable oom killing or always prefer a certain
         * task.
         */
-       points += p->signal->oom_score_adj;
+       points += p->signal->oom_score_adj * totalpages / 1000;
 
        /*
-        * Never return 0 for an eligible task that may be killed since it's
-        * possible that no single user task uses more than 0.1% of memory and
-        * no single admin tasks uses more than 3.0%.
+        * Never return 0 for an eligible task regardless of the root bonus and
+        * oom_score_adj (oom_score_adj can't be OOM_SCORE_ADJ_MIN here).
         */
-       if (points <= 0)
-               return 1;
-       return (points < 1000) ? points : 1000;
+       return points ? points : 1;
 }
 
 /*
@@ -314,7 +301,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
 {
        struct task_struct *g, *p;
        struct task_struct *chosen = NULL;
-       *ppoints = 0;
+       unsigned long chosen_points = 0;
 
        do_each_thread(g, p) {
                unsigned int points;
@@ -354,7 +341,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
                         */
                        if (p == current) {
                                chosen = p;
-                               *ppoints = 1000;
+                               chosen_points = ULONG_MAX;
                        } else if (!force_kill) {
                                /*
                                 * If this task is not being ptraced on exit,
@@ -367,12 +354,13 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
                }
 
                points = oom_badness(p, memcg, nodemask, totalpages);
-               if (points > *ppoints) {
+               if (points > chosen_points) {
                        chosen = p;
-                       *ppoints = points;
+                       chosen_points = points;
                }
        } while_each_thread(g, p);
 
+       *ppoints = chosen_points * 1000 / totalpages;
        return chosen;
 }
 
@@ -572,7 +560,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
        }
 
        check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL);
-       limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT;
+       limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1;
        read_lock(&tasklist_lock);
        p = select_bad_process(&points, limit, memcg, NULL, false);
        if (p && PTR_ERR(p) != -1UL)