-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinux-2.6-540-oom-kill.patch
207 lines (200 loc) · 5.03 KB
/
linux-2.6-540-oom-kill.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Index: linux-2.6.27.y/init/Kconfig
===================================================================
--- linux-2.6.27.y.orig/init/Kconfig
+++ linux-2.6.27.y/init/Kconfig
@@ -306,6 +306,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 SMP && CGROUPS
Index: linux-2.6.27.y/mm/oom_kill.c
===================================================================
--- linux-2.6.27.y.orig/mm/oom_kill.c
+++ linux-2.6.27.y/mm/oom_kill.c
@@ -177,6 +177,11 @@ unsigned long badness(struct task_struct
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.
*/
@@ -454,6 +459,7 @@ out:
read_unlock(&tasklist_lock);
cgroup_unlock();
}
+
#endif
static BLOCKING_NOTIFIER_HEAD(oom_notify_list);
@@ -519,6 +525,7 @@ void clear_zonelist_oom(struct zonelist
}
spin_unlock(&zone_scan_mutex);
}
+EXPORT_SYMBOL_GPL(clear_zonelist_oom);
/**
* out_of_memory - kill the "best" process when we run out of memory
@@ -602,3 +609,47 @@ out:
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 */
Index: linux-2.6.27.y/mm/oom_panic.c
===================================================================
--- /dev/null
+++ linux-2.6.27.y/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);
+}
Index: linux-2.6.27.y/mm/page_alloc.c
===================================================================
--- linux-2.6.27.y.orig/mm/page_alloc.c
+++ linux-2.6.27.y/mm/page_alloc.c
@@ -1588,11 +1588,12 @@ nofail_alloc:
if (page)
goto got_pg;
} else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
+#ifdef CONFIG_OOM_KILLER
if (!try_set_zone_oom(zonelist, gfp_mask)) {
schedule_timeout_uninterruptible(1);
goto restart;
}
-
+#endif
/*
* Go through the zonelist yet one more time, keep
* very high watermark here, this is only to catch
@@ -1603,18 +1604,24 @@ nofail_alloc:
order, zonelist, high_zoneidx,
ALLOC_WMARK_HIGH|ALLOC_CPUSET);
if (page) {
+#ifdef CONFIG_OOM_KILLER
clear_zonelist_oom(zonelist, gfp_mask);
+#endif
goto got_pg;
}
/* The OOM killer will not help higher order allocs so fail */
if (order > PAGE_ALLOC_COSTLY_ORDER) {
+#ifdef CONFIG_OOM_KILLER
clear_zonelist_oom(zonelist, gfp_mask);
+#endif
goto nopage;
}
out_of_memory(zonelist, gfp_mask, order);
+#ifdef CONFIG_OOM_KILLER
clear_zonelist_oom(zonelist, gfp_mask);
+#endif
goto restart;
}