diff options
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 |
