um: properly check all process' threads for a live mm
authorAnton Vorontsov <anton.vorontsov@linaro.org>
Thu, 31 May 2012 23:26:26 +0000 (16:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jun 2012 00:49:30 +0000 (17:49 -0700)
kill_off_processes() might miss a valid process, this is because checking
for process->mm is not enough.  Process' main thread may exit or detach
its mm via use_mm(), but other threads may still have a valid mm.

To catch this we use find_lock_task_mm(), which walks up all threads and
returns an appropriate task (with task lock held).

Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Cc: Richard Weinberger <richard@nod.at>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/um/kernel/reboot.c

index 1411f4e79f9a667d2bb5457badbbc73189a23780..3d15243ce69234c3ddbac961ef58b0282247a4e4 100644 (file)
@@ -6,6 +6,7 @@
 #include "linux/sched.h"
 #include "linux/spinlock.h"
 #include "linux/slab.h"
+#include "linux/oom.h"
 #include "kern_util.h"
 #include "os.h"
 #include "skas.h"
@@ -25,13 +26,13 @@ static void kill_off_processes(void)
 
                read_lock(&tasklist_lock);
                for_each_process(p) {
-                       task_lock(p);
-                       if (!p->mm) {
-                               task_unlock(p);
+                       struct task_struct *t;
+
+                       t = find_lock_task_mm(p);
+                       if (!t)
                                continue;
-                       }
-                       pid = p->mm->context.id.u.pid;
-                       task_unlock(p);
+                       pid = t->mm->context.id.u.pid;
+                       task_unlock(t);
                        os_kill_ptraced_process(pid, 1);
                }
                read_unlock(&tasklist_lock);