]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/oom_kill.c
r8169: make room for more phy init changes
[linux-2.6-omap-h63xx.git] / mm / oom_kill.c
index 6e999c88c503ce5f3997c0726cb23033d7119705..a64decb5b13fb3922e05a70559855dde685b57b4 100644 (file)
@@ -27,7 +27,8 @@
 #include <linux/notifier.h>
 
 int sysctl_panic_on_oom;
-static DEFINE_MUTEX(zone_scan_mutex);
+int sysctl_oom_kill_allocating_task;
+static DEFINE_SPINLOCK(zone_scan_mutex);
 /* #define DEBUG */
 
 /**
@@ -142,7 +143,7 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
         * because p may have allocated or otherwise mapped memory on
         * this node before. However it will be less likely.
         */
-       if (!cpuset_excl_nodes_overlap(p))
+       if (!cpuset_mems_allowed_intersects(current, p))
                points /= 8;
 
        /*
@@ -332,12 +333,20 @@ static int oom_kill_task(struct task_struct *p)
        return 0;
 }
 
-static int oom_kill_process(struct task_struct *p, unsigned long points,
-               const char *message)
+static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
+                           unsigned long points, const char *message)
 {
        struct task_struct *c;
        struct list_head *tsk;
 
+       if (printk_ratelimit()) {
+               printk(KERN_WARNING "%s invoked oom-killer: "
+                       "gfp_mask=0x%x, order=%d, oomkilladj=%d\n",
+                       current->comm, gfp_mask, order, current->oomkilladj);
+               dump_stack();
+               show_mem();
+       }
+
        /*
         * If the task is already exiting, don't alarm the sysadmin or kill
         * its children or threads, just set TIF_MEMDIE so it can die quickly
@@ -387,7 +396,7 @@ int try_set_zone_oom(struct zonelist *zonelist)
 
        z = zonelist->zones;
 
-       mutex_lock(&zone_scan_mutex);
+       spin_lock(&zone_scan_mutex);
        do {
                if (zone_is_oom_locked(*z)) {
                        ret = 0;
@@ -404,7 +413,7 @@ int try_set_zone_oom(struct zonelist *zonelist)
                zone_set_flag(*z, ZONE_OOM_LOCKED);
        } while (*(++z) != NULL);
 out:
-       mutex_unlock(&zone_scan_mutex);
+       spin_unlock(&zone_scan_mutex);
        return ret;
 }
 
@@ -419,11 +428,11 @@ void clear_zonelist_oom(struct zonelist *zonelist)
 
        z = zonelist->zones;
 
-       mutex_lock(&zone_scan_mutex);
+       spin_lock(&zone_scan_mutex);
        do {
                zone_clear_flag(*z, ZONE_OOM_LOCKED);
        } while (*(++z) != NULL);
-       mutex_unlock(&zone_scan_mutex);
+       spin_unlock(&zone_scan_mutex);
 }
 
 /**
@@ -446,14 +455,6 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
                /* Got some memory back in the last second. */
                return;
 
-       if (printk_ratelimit()) {
-               printk(KERN_WARNING "%s invoked oom-killer: "
-                       "gfp_mask=0x%x, order=%d, oomkilladj=%d\n",
-                       current->comm, gfp_mask, order, current->oomkilladj);
-               dump_stack();
-               show_mem();
-       }
-
        if (sysctl_panic_on_oom == 2)
                panic("out of memory. Compulsory panic_on_oom is selected.\n");
 
@@ -462,23 +463,24 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
         * NUMA) that may require different handling.
         */
        constraint = constrained_alloc(zonelist, gfp_mask);
-       cpuset_lock();
        read_lock(&tasklist_lock);
 
        switch (constraint) {
        case CONSTRAINT_MEMORY_POLICY:
-               oom_kill_process(current, points,
+               oom_kill_process(current, gfp_mask, order, points,
                                "No available memory (MPOL_BIND)");
                break;
 
-       case CONSTRAINT_CPUSET:
-               oom_kill_process(current, points,
-                               "No available memory in cpuset");
-               break;
-
        case CONSTRAINT_NONE:
                if (sysctl_panic_on_oom)
                        panic("out of memory. panic_on_oom is selected\n");
+               /* Fall-through */
+       case CONSTRAINT_CPUSET:
+               if (sysctl_oom_kill_allocating_task) {
+                       oom_kill_process(current, gfp_mask, order, points,
+                                       "Out of memory (oom_kill_allocating_task)");
+                       break;
+               }
 retry:
                /*
                 * Rambo mode: Shoot down a process and hope it solves whatever
@@ -492,11 +494,11 @@ retry:
                /* Found nothing?!?! Either we hang forever, or we panic. */
                if (!p) {
                        read_unlock(&tasklist_lock);
-                       cpuset_unlock();
                        panic("Out of memory and no killable processes...\n");
                }
 
-               if (oom_kill_process(p, points, "Out of memory"))
+               if (oom_kill_process(p, points, gfp_mask, order,
+                                    "Out of memory"))
                        goto retry;
 
                break;
@@ -504,7 +506,6 @@ retry:
 
 out:
        read_unlock(&tasklist_lock);
-       cpuset_unlock();
 
        /*
         * Give "p" a good chance of killing itself before we