more patches
[linux-2.6.git] / linux-2.6-540-oom-kill.patch
diff --git a/linux-2.6-540-oom-kill.patch b/linux-2.6-540-oom-kill.patch
new file mode 100644 (file)
index 0000000..4da8e3f
--- /dev/null
@@ -0,0 +1,200 @@
+diff --git a/mm/oom_panic.c b/mm/oom_panic.c
+new file mode 100644
+index 0000000..4230ae5
+--- /dev/null
++++ b/mm/oom_panic.c
+@@ -0,0 +1,51 @@
++/* 
++ * Just panic() instead of the default behavior of selecting processes
++ * for death.
++ *
++ * Based on
++ * Modular OOM handlers for 2.6.4 (C) 2003,2004 Tvrtko A. Ursulin
++ * and
++ * linux/mm/oom_kill.c (C) 1998,2000 Rik van Riel.
++ *
++ * Mark Huang <mlhuang@cs.princeton.edu>
++ *
++ * $Id: oom_panic.c,v 1.1 2004/10/01 17:54:48 mlhuang Exp $
++ */
++
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/swap.h>
++
++/**
++ * out_of_memory - is the system out of memory?
++ */
++void out_of_memory(int gfp_mask)
++{
++      /*
++       * oom_lock protects out_of_memory()'s static variables.
++       * It's a global lock; this is not performance-critical.
++       */
++      static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
++      static unsigned long count;
++
++      spin_lock(&oom_lock);
++
++      /*
++       * If we have gotten only a few failures,
++       * we're not really oom. 
++       */
++      if (++count < 10)
++              goto out_unlock;
++
++      /*
++       * Ok, really out of memory. Panic.
++       */
++
++      printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
++      show_free_areas();
++
++      panic("Out Of Memory");
++
++out_unlock:
++      spin_unlock(&oom_lock);
++}
+
+commit 2e378e38451e7b3929110dc6f13d48587a169afe
+Author: root <root@rhel6.(none)>
+Date:   Thu Apr 29 10:08:21 2010 -0400
+
+    linux-2.6-540-oom-kill.patch
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 87fe242..cc782ea 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -548,6 +548,23 @@ config CGROUP_DEVICE
+         Provides a cgroup implementing whitelists for devices which
+         a process in the cgroup can mknod or open.
++config OOM_PANIC
++      bool "OOM Panic"
++      default y
++      ---help---
++        This option enables panic() to be called when a system is out of
++        memory. This feature along with /proc/sys/kernel/panic allows a
++        different behavior on out-of-memory conditions when the standard
++        behavior (killing processes in an attempt to recover) does not
++        make sense.
++
++        If unsure, say N.
++
++config OOM_KILL
++      bool
++      depends on !OOM_PANIC
++      default y
++
+ config CPUSETS
+       bool "Cpuset support"
+       depends on CGROUPS
+diff --git a/mm/oom_kill.c b/mm/oom_kill.c
+index e0ba2e1..bb123cf 100644
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -209,6 +209,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
+       return points;
+ }
++#if defined(CONFIG_OOM_PANIC) && defined(CONFIG_OOM_KILLER)
++#warning Only define OOM_PANIC or OOM_KILLER; not both
++#endif
++
++#ifdef CONFIG_OOM_KILLER
+ /*
+  * Determine the type of allocation constraint.
+  */
+@@ -479,6 +484,7 @@ retry:
+ out:
+       read_unlock(&tasklist_lock);
+ }
++
+ #endif
+ static BLOCKING_NOTIFIER_HEAD(oom_notify_list);
+@@ -544,6 +550,7 @@ void clear_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_mask)
+       }
+       spin_unlock(&zone_scan_lock);
+ }
++EXPORT_SYMBOL_GPL(clear_zonelist_oom);
+ long vs_oom_action(unsigned int);
+@@ -675,3 +682,47 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
+       if (!test_thread_flag(TIF_MEMDIE))
+               schedule_timeout_uninterruptible(1);
+ }
++#endif /* CONFIG_OOM_KILLER */
++
++#ifdef CONFIG_OOM_PANIC
++/**
++ * out_of_memory - panic if the system out of memory?
++ */
++void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
++{
++      /*
++       * oom_lock protects out_of_memory()'s static variables.
++       * It's a global lock; this is not performance-critical.
++       */
++      static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
++      static unsigned long count;
++
++      spin_lock(&oom_lock);
++
++      /*
++       * If we have gotten only a few failures,
++       * we're not really oom. 
++       */
++      if (++count >= 10) {
++              /*
++               * Ok, really out of memory. Panic.
++               */
++
++              printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
++              show_free_areas();
++
++              panic("Out Of Memory");
++      }
++      spin_unlock(&oom_lock);
++}
++
++#ifdef CONFIG_CGROUP_MEM_RES_CTLR
++void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
++{
++      cgroup_lock();
++      panic("Memory cgroup out Of Memory");
++      cgroup_unlock();
++}
++
++#endif
++#endif /*  CONFIG_OOM_PANIC */
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 4b70600..4830639 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1642,11 +1642,13 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
+ {
+       struct page *page;
++#ifdef CONFIG_OOM_KILLER
+       /* Acquire the OOM killer lock for the zones in zonelist */
+       if (!try_set_zone_oom(zonelist, gfp_mask)) {
+               schedule_timeout_uninterruptible(1);
+               return NULL;
+       }
++#endif
+       /*
+        * Go through the zonelist yet one more time, keep very high watermark
+@@ -1668,7 +1670,9 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
+       out_of_memory(zonelist, gfp_mask, order);
+ out:
++#ifdef CONFIG_OOM_KILLER
+       clear_zonelist_oom(zonelist, gfp_mask);
++#endif
+       return page;
+ }