KVM: VMX: Properly return error to userspace on vmentry failure
[linux-2.6.git] / mm / oom_kill.c
index 6bb8a7a..709aedf 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/oom.h>
 #include <linux/mm.h>
 #include <linux/err.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/swap.h>
 #include <linux/timex.h>
@@ -196,27 +197,46 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
 /*
  * Determine the type of allocation constraint.
  */
-static inline enum oom_constraint constrained_alloc(struct zonelist *zonelist,
-                                                   gfp_t gfp_mask)
-{
 #ifdef CONFIG_NUMA
+static enum oom_constraint constrained_alloc(struct zonelist *zonelist,
+                                   gfp_t gfp_mask, nodemask_t *nodemask)
+{
        struct zone *zone;
        struct zoneref *z;
        enum zone_type high_zoneidx = gfp_zone(gfp_mask);
-       nodemask_t nodes = node_states[N_HIGH_MEMORY];
 
-       for_each_zone_zonelist(zone, z, zonelist, high_zoneidx)
-               if (cpuset_zone_allowed_softwall(zone, gfp_mask))
-                       node_clear(zone_to_nid(zone), nodes);
-               else
-                       return CONSTRAINT_CPUSET;
+       /*
+        * Reach here only when __GFP_NOFAIL is used. So, we should avoid
+        * to kill current.We have to random task kill in this case.
+        * Hopefully, CONSTRAINT_THISNODE...but no way to handle it, now.
+        */
+       if (gfp_mask & __GFP_THISNODE)
+               return CONSTRAINT_NONE;
 
-       if (!nodes_empty(nodes))
+       /*
+        * The nodemask here is a nodemask passed to alloc_pages(). Now,
+        * cpuset doesn't use this nodemask for its hardwall/softwall/hierarchy
+        * feature. mempolicy is an only user of nodemask here.
+        * check mempolicy's nodemask contains all N_HIGH_MEMORY
+        */
+       if (nodemask && !nodes_subset(node_states[N_HIGH_MEMORY], *nodemask))
                return CONSTRAINT_MEMORY_POLICY;
-#endif
+
+       /* Check this allocation failure is caused by cpuset's wall function */
+       for_each_zone_zonelist_nodemask(zone, z, zonelist,
+                       high_zoneidx, nodemask)
+               if (!cpuset_zone_allowed_softwall(zone, gfp_mask))
+                       return CONSTRAINT_CPUSET;
 
        return CONSTRAINT_NONE;
 }
+#else
+static enum oom_constraint constrained_alloc(struct zonelist *zonelist,
+                               gfp_t gfp_mask, nodemask_t *nodemask)
+{
+       return CONSTRAINT_NONE;
+}
+#endif
 
 /*
  * Simple selection loop. We chose the process with the highest
@@ -337,7 +357,8 @@ static void dump_tasks(const struct mem_cgroup *mem)
        } while_each_thread(g, p);
 }
 
-static void dump_header(gfp_t gfp_mask, int order, struct mem_cgroup *mem)
+static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
+                                                       struct mem_cgroup *mem)
 {
        pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
                "oom_adj=%d\n",
@@ -346,7 +367,7 @@ static void dump_header(gfp_t gfp_mask, int order, struct mem_cgroup *mem)
        cpuset_print_task_mems_allowed(current);
        task_unlock(current);
        dump_stack();
-       mem_cgroup_print_oom_info(mem, current);
+       mem_cgroup_print_oom_info(mem, p);
        show_mem();
        if (sysctl_oom_dump_tasks)
                dump_tasks(mem);
@@ -381,8 +402,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose)
                       "vsz:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
                       task_pid_nr(p), p->comm,
                       K(p->mm->total_vm),
-                      K(get_mm_counter(p->mm, anon_rss)),
-                      K(get_mm_counter(p->mm, file_rss)));
+                      K(get_mm_counter(p->mm, MM_ANONPAGES)),
+                      K(get_mm_counter(p->mm, MM_FILEPAGES)));
        task_unlock(p);
 
        /*
@@ -421,7 +442,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
        struct task_struct *c;
 
        if (printk_ratelimit())
-               dump_header(gfp_mask, order, mem);
+               dump_header(p, gfp_mask, order, mem);
 
        /*
         * If the task is already exiting, don't alarm the sysadmin or kill
@@ -439,6 +460,8 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
        list_for_each_entry(c, &p->children, sibling) {
                if (c->mm == p->mm)
                        continue;
+               if (mem && !task_in_mem_cgroup(c, mem))
+                       continue;
                if (!oom_kill_task(c))
                        return 0;
        }
@@ -451,15 +474,14 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
        unsigned long points = 0;
        struct task_struct *p;
 
+       if (sysctl_panic_on_oom == 2)
+               panic("out of memory(memcg). panic_on_oom is selected.\n");
        read_lock(&tasklist_lock);
 retry:
        p = select_bad_process(&points, mem);
-       if (PTR_ERR(p) == -1UL)
+       if (!p || PTR_ERR(p) == -1UL)
                goto out;
 
-       if (!p)
-               p = current;
-
        if (oom_kill_process(p, gfp_mask, 0, points, mem,
                                "Memory cgroup out of memory"))
                goto retry;
@@ -557,7 +579,7 @@ retry:
        /* Found nothing?!?! Either we hang forever, or we panic. */
        if (!p) {
                read_unlock(&tasklist_lock);
-               dump_header(gfp_mask, order, NULL);
+               dump_header(NULL, gfp_mask, order, NULL);
                panic("Out of memory and no killable processes...\n");
        }
 
@@ -579,13 +601,6 @@ void pagefault_out_of_memory(void)
                /* Got some memory back in the last second. */
                return;
 
-       /*
-        * If this is from memcg, oom-killer is already invoked.
-        * and not worth to go system-wide-oom.
-        */
-       if (mem_cgroup_oom_called(current))
-               goto rest_and_return;
-
        if (sysctl_panic_on_oom)
                panic("out of memory from page fault. panic_on_oom is selected.\n");
 
@@ -597,7 +612,6 @@ void pagefault_out_of_memory(void)
         * Give "p" a good chance of killing itself before we
         * retry to allocate memory.
         */
-rest_and_return:
        if (!test_thread_flag(TIF_MEMDIE))
                schedule_timeout_uninterruptible(1);
 }
@@ -613,7 +627,8 @@ rest_and_return:
  * OR try to be smart about which process to kill. Note that we
  * don't have to be perfect here, we just have to be good.
  */
-void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
+void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
+               int order, nodemask_t *nodemask)
 {
        unsigned long freed = 0;
        enum oom_constraint constraint;
@@ -624,7 +639,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
                return;
 
        if (sysctl_panic_on_oom == 2) {
-               dump_header(gfp_mask, order, NULL);
+               dump_header(NULL, gfp_mask, order, NULL);
                panic("out of memory. Compulsory panic_on_oom is selected.\n");
        }
 
@@ -632,7 +647,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
         * Check if there were limitations on the allocation (only relevant for
         * NUMA) that may require different handling.
         */
-       constraint = constrained_alloc(zonelist, gfp_mask);
+       constraint = constrained_alloc(zonelist, gfp_mask, nodemask);
        read_lock(&tasklist_lock);
 
        switch (constraint) {
@@ -643,7 +658,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
 
        case CONSTRAINT_NONE:
                if (sysctl_panic_on_oom) {
-                       dump_header(gfp_mask, order, NULL);
+                       dump_header(NULL, gfp_mask, order, NULL);
                        panic("out of memory. panic_on_oom is selected\n");
                }
                /* Fall-through */