Setting tag linux-2.6-32-36
[linux-2.6.git] / linux-2.6-540-oom-kill.patch
1 diff --git a/mm/oom_panic.c b/mm/oom_panic.c
2 new file mode 100644
3 index 0000000..4230ae5
4 --- /dev/null
5 +++ b/mm/oom_panic.c
6 @@ -0,0 +1,51 @@
7 +/* 
8 + * Just panic() instead of the default behavior of selecting processes
9 + * for death.
10 + *
11 + * Based on
12 + * Modular OOM handlers for 2.6.4 (C) 2003,2004 Tvrtko A. Ursulin
13 + * and
14 + * linux/mm/oom_kill.c (C) 1998,2000 Rik van Riel.
15 + *
16 + * Mark Huang <mlhuang@cs.princeton.edu>
17 + *
18 + * $Id: oom_panic.c,v 1.1 2004/10/01 17:54:48 mlhuang Exp $
19 + */
20 +
21 +#include <linux/mm.h>
22 +#include <linux/sched.h>
23 +#include <linux/swap.h>
24 +
25 +/**
26 + * out_of_memory - is the system out of memory?
27 + */
28 +void out_of_memory(int gfp_mask)
29 +{
30 +       /*
31 +        * oom_lock protects out_of_memory()'s static variables.
32 +        * It's a global lock; this is not performance-critical.
33 +        */
34 +       static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
35 +       static unsigned long count;
36 +
37 +       spin_lock(&oom_lock);
38 +
39 +       /*
40 +        * If we have gotten only a few failures,
41 +        * we're not really oom. 
42 +        */
43 +       if (++count < 10)
44 +               goto out_unlock;
45 +
46 +       /*
47 +        * Ok, really out of memory. Panic.
48 +        */
49 +
50 +       printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
51 +       show_free_areas();
52 +
53 +       panic("Out Of Memory");
54 +
55 +out_unlock:
56 +       spin_unlock(&oom_lock);
57 +}
58 diff --git a/init/Kconfig b/init/Kconfig
59 index 87fe242..cc782ea 100644
60 --- a/init/Kconfig
61 +++ b/init/Kconfig
62 @@ -548,6 +548,23 @@ config CGROUP_DEVICE
63           Provides a cgroup implementing whitelists for devices which
64           a process in the cgroup can mknod or open.
65  
66 +config OOM_PANIC
67 +       bool "OOM Panic"
68 +       default y
69 +       ---help---
70 +         This option enables panic() to be called when a system is out of
71 +         memory. This feature along with /proc/sys/kernel/panic allows a
72 +         different behavior on out-of-memory conditions when the standard
73 +         behavior (killing processes in an attempt to recover) does not
74 +         make sense.
75 +
76 +         If unsure, say N.
77 +
78 +config OOM_KILL
79 +       bool
80 +       depends on !OOM_PANIC
81 +       default y
82 +
83  config CPUSETS
84         bool "Cpuset support"
85         depends on CGROUPS
86 diff --git a/mm/oom_kill.c b/mm/oom_kill.c
87 index e0ba2e1..bb123cf 100644
88 --- a/mm/oom_kill.c
89 +++ b/mm/oom_kill.c
90 @@ -209,6 +209,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
91         return points;
92  }
93  
94 +#if defined(CONFIG_OOM_PANIC) && defined(CONFIG_OOM_KILLER)
95 +#warning Only define OOM_PANIC or OOM_KILLER; not both
96 +#endif
97 +
98 +#ifdef CONFIG_OOM_KILLER
99  /*
100   * Determine the type of allocation constraint.
101   */
102 @@ -479,6 +484,7 @@ retry:
103  out:
104         read_unlock(&tasklist_lock);
105  }
106 +
107  #endif
108  
109  static BLOCKING_NOTIFIER_HEAD(oom_notify_list);
110 @@ -544,6 +550,7 @@ void clear_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_mask)
111         }
112         spin_unlock(&zone_scan_lock);
113  }
114 +EXPORT_SYMBOL_GPL(clear_zonelist_oom);
115  
116  long vs_oom_action(unsigned int);
117  
118 @@ -675,3 +682,47 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
119         if (!test_thread_flag(TIF_MEMDIE))
120                 schedule_timeout_uninterruptible(1);
121  }
122 +#endif /* CONFIG_OOM_KILLER */
123 +
124 +#ifdef CONFIG_OOM_PANIC
125 +/**
126 + * out_of_memory - panic if the system out of memory?
127 + */
128 +void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
129 +{
130 +       /*
131 +        * oom_lock protects out_of_memory()'s static variables.
132 +        * It's a global lock; this is not performance-critical.
133 +        */
134 +       static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
135 +       static unsigned long count;
136 +
137 +       spin_lock(&oom_lock);
138 +
139 +       /*
140 +        * If we have gotten only a few failures,
141 +        * we're not really oom. 
142 +        */
143 +       if (++count >= 10) {
144 +               /*
145 +                * Ok, really out of memory. Panic.
146 +                */
147 +
148 +               printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
149 +               show_free_areas();
150 +
151 +               panic("Out Of Memory");
152 +       }
153 +       spin_unlock(&oom_lock);
154 +}
155 +
156 +#ifdef CONFIG_CGROUP_MEM_RES_CTLR
157 +void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
158 +{
159 +       cgroup_lock();
160 +       panic("Memory cgroup out Of Memory");
161 +       cgroup_unlock();
162 +}
163 +
164 +#endif
165 +#endif /*  CONFIG_OOM_PANIC */
166 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
167 index 4b70600..4830639 100644
168 --- a/mm/page_alloc.c
169 +++ b/mm/page_alloc.c
170 @@ -1642,11 +1642,13 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
171  {
172         struct page *page;
173  
174 +#ifdef CONFIG_OOM_KILLER
175         /* Acquire the OOM killer lock for the zones in zonelist */
176         if (!try_set_zone_oom(zonelist, gfp_mask)) {
177                 schedule_timeout_uninterruptible(1);
178                 return NULL;
179         }
180 +#endif
181  
182         /*
183          * Go through the zonelist yet one more time, keep very high watermark
184 @@ -1668,7 +1670,9 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
185         out_of_memory(zonelist, gfp_mask, order);
186  
187  out:
188 +#ifdef CONFIG_OOM_KILLER
189         clear_zonelist_oom(zonelist, gfp_mask);
190 +#endif
191         return page;
192  }
193