diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2010-08-09 20:19:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:45:01 -0400 |
commit | 26ebc984913b6a8d86d724b3a79d2ed4ed574612 (patch) | |
tree | 9d293c6f8b1bc5120beaa173590dcd83cd0e2eb0 /mm | |
parent | f88ccad5886d5a864b8b0d48c666ee9998dec53f (diff) |
oom: /proc/<pid>/oom_score treat kernel thread honestly
If a kernel thread is using use_mm(), badness() returns a positive value.
This is not a big issue because caller take care of it correctly. But
there is one exception, /proc/<pid>/oom_score calls badness() directly and
doesn't care that the task is a regular process.
Another example, /proc/1/oom_score return !0 value. But it's unkillable.
This incorrectness makes administration a little confusing.
This patch fixes it.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: David Rientjes <rientjes@google.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/oom_kill.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 3999747aef48..867bd26274b4 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -139,8 +139,8 @@ static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem, | |||
139 | * algorithm has been meticulously tuned to meet the principle | 139 | * algorithm has been meticulously tuned to meet the principle |
140 | * of least surprise ... (be careful when you change it) | 140 | * of least surprise ... (be careful when you change it) |
141 | */ | 141 | */ |
142 | 142 | unsigned long badness(struct task_struct *p, struct mem_cgroup *mem, | |
143 | unsigned long badness(struct task_struct *p, unsigned long uptime) | 143 | const nodemask_t *nodemask, unsigned long uptime) |
144 | { | 144 | { |
145 | unsigned long points, cpu_time, run_time; | 145 | unsigned long points, cpu_time, run_time; |
146 | struct task_struct *child; | 146 | struct task_struct *child; |
@@ -150,6 +150,8 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
150 | unsigned long utime; | 150 | unsigned long utime; |
151 | unsigned long stime; | 151 | unsigned long stime; |
152 | 152 | ||
153 | if (oom_unkillable_task(p, mem, nodemask)) | ||
154 | return 0; | ||
153 | if (oom_adj == OOM_DISABLE) | 155 | if (oom_adj == OOM_DISABLE) |
154 | return 0; | 156 | return 0; |
155 | 157 | ||
@@ -351,7 +353,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints, | |||
351 | if (p->signal->oom_adj == OOM_DISABLE) | 353 | if (p->signal->oom_adj == OOM_DISABLE) |
352 | continue; | 354 | continue; |
353 | 355 | ||
354 | points = badness(p, uptime.tv_sec); | 356 | points = badness(p, mem, nodemask, uptime.tv_sec); |
355 | if (points > *ppoints || !chosen) { | 357 | if (points > *ppoints || !chosen) { |
356 | chosen = p; | 358 | chosen = p; |
357 | *ppoints = points; | 359 | *ppoints = points; |
@@ -482,11 +484,10 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
482 | 484 | ||
483 | if (child->mm == p->mm) | 485 | if (child->mm == p->mm) |
484 | continue; | 486 | continue; |
485 | if (oom_unkillable_task(p, mem, nodemask)) | ||
486 | continue; | ||
487 | 487 | ||
488 | /* badness() returns 0 if the thread is unkillable */ | 488 | /* badness() returns 0 if the thread is unkillable */ |
489 | child_points = badness(child, uptime.tv_sec); | 489 | child_points = badness(child, mem, nodemask, |
490 | uptime.tv_sec); | ||
490 | if (child_points > victim_points) { | 491 | if (child_points > victim_points) { |
491 | victim = child; | 492 | victim = child; |
492 | victim_points = child_points; | 493 | victim_points = child_points; |