diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:41:28 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:41:28 -0400 |
commit | 142e27fc8a3619471669d6241784eec9167c47d1 (patch) | |
tree | e88850b63ec910ee28874f93c43fb66421bb8119 /mm/oom_kill.c | |
parent | a9053d0494d3c92807701c0f47df61d50c971581 (diff) | |
parent | caf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r-- | mm/oom_kill.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 1e56076672f5..5ec8da12cfd9 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -6,8 +6,8 @@ | |||
6 | * for goading me into coding this file... | 6 | * for goading me into coding this file... |
7 | * | 7 | * |
8 | * The routines in this file are used to kill a process when | 8 | * The routines in this file are used to kill a process when |
9 | * we're seriously out of memory. This gets called from kswapd() | 9 | * we're seriously out of memory. This gets called from __alloc_pages() |
10 | * in linux/mm/vmscan.c when we really run out of memory. | 10 | * in mm/page_alloc.c when we really run out of memory. |
11 | * | 11 | * |
12 | * Since we won't call these routines often (on a well-configured | 12 | * Since we won't call these routines often (on a well-configured |
13 | * machine) this file will double as a 'coding guide' and a signpost | 13 | * machine) this file will double as a 'coding guide' and a signpost |
@@ -20,13 +20,14 @@ | |||
20 | #include <linux/swap.h> | 20 | #include <linux/swap.h> |
21 | #include <linux/timex.h> | 21 | #include <linux/timex.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
23 | #include <linux/cpuset.h> | ||
23 | 24 | ||
24 | /* #define DEBUG */ | 25 | /* #define DEBUG */ |
25 | 26 | ||
26 | /** | 27 | /** |
27 | * oom_badness - calculate a numeric value for how bad this task has been | 28 | * oom_badness - calculate a numeric value for how bad this task has been |
28 | * @p: task struct of which task we should calculate | 29 | * @p: task struct of which task we should calculate |
29 | * @p: current uptime in seconds | 30 | * @uptime: current uptime in seconds |
30 | * | 31 | * |
31 | * The formula used is relatively simple and documented inline in the | 32 | * The formula used is relatively simple and documented inline in the |
32 | * function. The main rationale is that we want to select a good task | 33 | * function. The main rationale is that we want to select a good task |
@@ -57,9 +58,9 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Processes which fork a lot of child processes are likely | 60 | * Processes which fork a lot of child processes are likely |
60 | * a good choice. We add the vmsize of the childs if they | 61 | * a good choice. We add the vmsize of the children if they |
61 | * have an own mm. This prevents forking servers to flood the | 62 | * have an own mm. This prevents forking servers to flood the |
62 | * machine with an endless amount of childs | 63 | * machine with an endless amount of children |
63 | */ | 64 | */ |
64 | list_for_each(tsk, &p->children) { | 65 | list_for_each(tsk, &p->children) { |
65 | struct task_struct *chld; | 66 | struct task_struct *chld; |
@@ -143,28 +144,36 @@ static struct task_struct * select_bad_process(void) | |||
143 | struct timespec uptime; | 144 | struct timespec uptime; |
144 | 145 | ||
145 | do_posix_clock_monotonic_gettime(&uptime); | 146 | do_posix_clock_monotonic_gettime(&uptime); |
146 | do_each_thread(g, p) | 147 | do_each_thread(g, p) { |
148 | unsigned long points; | ||
149 | int releasing; | ||
150 | |||
147 | /* skip the init task with pid == 1 */ | 151 | /* skip the init task with pid == 1 */ |
148 | if (p->pid > 1 && p->oomkilladj != OOM_DISABLE) { | 152 | if (p->pid == 1) |
149 | unsigned long points; | 153 | continue; |
150 | 154 | if (p->oomkilladj == OOM_DISABLE) | |
151 | /* | 155 | continue; |
152 | * This is in the process of releasing memory so wait it | 156 | /* If p's nodes don't overlap ours, it won't help to kill p. */ |
153 | * to finish before killing some other task by mistake. | 157 | if (!cpuset_excl_nodes_overlap(p)) |
154 | */ | 158 | continue; |
155 | if ((unlikely(test_tsk_thread_flag(p, TIF_MEMDIE)) || (p->flags & PF_EXITING)) && | 159 | |
156 | !(p->flags & PF_DEAD)) | 160 | /* |
157 | return ERR_PTR(-1UL); | 161 | * This is in the process of releasing memory so for wait it |
158 | if (p->flags & PF_SWAPOFF) | 162 | * to finish before killing some other task by mistake. |
159 | return p; | 163 | */ |
160 | 164 | releasing = test_tsk_thread_flag(p, TIF_MEMDIE) || | |
161 | points = badness(p, uptime.tv_sec); | 165 | p->flags & PF_EXITING; |
162 | if (points > maxpoints || !chosen) { | 166 | if (releasing && !(p->flags & PF_DEAD)) |
163 | chosen = p; | 167 | return ERR_PTR(-1UL); |
164 | maxpoints = points; | 168 | if (p->flags & PF_SWAPOFF) |
165 | } | 169 | return p; |
170 | |||
171 | points = badness(p, uptime.tv_sec); | ||
172 | if (points > maxpoints || !chosen) { | ||
173 | chosen = p; | ||
174 | maxpoints = points; | ||
166 | } | 175 | } |
167 | while_each_thread(g, p); | 176 | } while_each_thread(g, p); |
168 | return chosen; | 177 | return chosen; |
169 | } | 178 | } |
170 | 179 | ||
@@ -189,7 +198,8 @@ static void __oom_kill_task(task_t *p) | |||
189 | return; | 198 | return; |
190 | } | 199 | } |
191 | task_unlock(p); | 200 | task_unlock(p); |
192 | printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm); | 201 | printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", |
202 | p->pid, p->comm); | ||
193 | 203 | ||
194 | /* | 204 | /* |
195 | * We give our sacrificial lamb high priority and access to | 205 | * We give our sacrificial lamb high priority and access to |