aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2010-08-09 20:18:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-09 23:44:56 -0400
commitc55db95788a2a55a77f5a3ced1e59578710440b2 (patch)
tree275a0c97bfe408ea926dfe14864e476d719859e9 /mm
parentdd8e8f405ca386c7ce7cbb996ccd985d283b0e03 (diff)
oom: dump_tasks use find_lock_task_mm too
dump_task() should use find_lock_task_mm() too. It is necessary for protecting task-exiting race. dump_tasks() currently filters any task that does not have an attached ->mm since it incorrectly assumes that it must either be in the process of exiting and has detached its memory or that it's a kernel thread; multithreaded tasks may actually have subthreads that have a valid ->mm pointer and thus those threads should actually be displayed. This change finds those threads, if they exist, and emit their information along with the rest of the candidate tasks for kill. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: David Rientjes <rientjes@google.com> Cc: Balbir Singh <balbir@in.ibm.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.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 9a686aa35a48..5285da9a9c1a 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -336,35 +336,38 @@ static struct task_struct *select_bad_process(unsigned long *ppoints,
336 */ 336 */
337static void dump_tasks(const struct mem_cgroup *mem) 337static void dump_tasks(const struct mem_cgroup *mem)
338{ 338{
339 struct task_struct *g, *p; 339 struct task_struct *p;
340 struct task_struct *task;
340 341
341 printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj " 342 printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj "
342 "name\n"); 343 "name\n");
343 do_each_thread(g, p) { 344 for_each_process(p) {
344 struct mm_struct *mm; 345 /*
345 346 * We don't have is_global_init() check here, because the old
346 if (mem && !task_in_mem_cgroup(p, mem)) 347 * code do that. printing init process is not big matter. But
348 * we don't hope to make unnecessary compatibility breaking.
349 */
350 if (p->flags & PF_KTHREAD)
347 continue; 351 continue;
348 if (!thread_group_leader(p)) 352 if (mem && !task_in_mem_cgroup(p, mem))
349 continue; 353 continue;
350 354
351 task_lock(p); 355 task = find_lock_task_mm(p);
352 mm = p->mm; 356 if (!task) {
353 if (!mm) {
354 /* 357 /*
355 * total_vm and rss sizes do not exist for tasks with no 358 * Probably oom vs task-exiting race was happen and ->mm
356 * mm so there's no need to report them; they can't be 359 * have been detached. thus there's no need to report
357 * oom killed anyway. 360 * them; they can't be oom killed anyway.
358 */ 361 */
359 task_unlock(p);
360 continue; 362 continue;
361 } 363 }
364
362 printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", 365 printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n",
363 p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm, 366 task->pid, __task_cred(task)->uid, task->tgid,
364 get_mm_rss(mm), (int)task_cpu(p), p->signal->oom_adj, 367 task->mm->total_vm, get_mm_rss(task->mm),
365 p->comm); 368 (int)task_cpu(task), task->signal->oom_adj, p->comm);
366 task_unlock(p); 369 task_unlock(task);
367 } while_each_thread(g, p); 370 }
368} 371}
369 372
370static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, 373static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,