Skip to content

Commit c55db95

Browse files
kosakitorvalds
authored andcommitted
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 <[email protected]> Signed-off-by: David Rientjes <[email protected]> Cc: Balbir Singh <[email protected]> Cc: Oleg Nesterov <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent dd8e8f4 commit c55db95

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

mm/oom_kill.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -336,35 +336,38 @@ static struct task_struct *select_bad_process(unsigned long *ppoints,
336336
*/
337337
static void dump_tasks(const struct mem_cgroup *mem)
338338
{
339-
struct task_struct *g, *p;
339+
struct task_struct *p;
340+
struct task_struct *task;
340341

341342
printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj "
342343
"name\n");
343-
do_each_thread(g, p) {
344-
struct mm_struct *mm;
345-
346-
if (mem && !task_in_mem_cgroup(p, mem))
344+
for_each_process(p) {
345+
/*
346+
* We don't have is_global_init() check here, because the old
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)
347351
continue;
348-
if (!thread_group_leader(p))
352+
if (mem && !task_in_mem_cgroup(p, mem))
349353
continue;
350354

351-
task_lock(p);
352-
mm = p->mm;
353-
if (!mm) {
355+
task = find_lock_task_mm(p);
356+
if (!task) {
354357
/*
355-
* total_vm and rss sizes do not exist for tasks with no
356-
* mm so there's no need to report them; they can't be
357-
* oom killed anyway.
358+
* Probably oom vs task-exiting race was happen and ->mm
359+
* have been detached. thus there's no need to report
360+
* them; they can't be oom killed anyway.
358361
*/
359-
task_unlock(p);
360362
continue;
361363
}
364+
362365
printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n",
363-
p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm,
364-
get_mm_rss(mm), (int)task_cpu(p), p->signal->oom_adj,
365-
p->comm);
366-
task_unlock(p);
367-
} while_each_thread(g, p);
366+
task->pid, __task_cred(task)->uid, task->tgid,
367+
task->mm->total_vm, get_mm_rss(task->mm),
368+
(int)task_cpu(task), task->signal->oom_adj, p->comm);
369+
task_unlock(task);
370+
}
368371
}
369372

370373
static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,

0 commit comments

Comments
 (0)