[PATCH] coredump: optimize ->mm users traversal
authorOleg Nesterov <oleg@tv-sign.ru>
Mon, 26 Jun 2006 07:26:05 +0000 (00:26 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 26 Jun 2006 16:58:26 +0000 (09:58 -0700)
zap_threads() iterates over all threads to find those ones which share
current->mm.  All threads in the thread group share the same ->mm, so we can
skip entire thread group if it has another ->mm.

This patch shifts the killing of thread group into the newly added
zap_process() function.  This looks as unnecessary complication, but it is
used in further patches.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/exec.c

index fffea1eef8dcd2311ed27033f249ef86d7535a9f..80fe7bcfa0942bf2b1026ec0fb55d1fafefaa70c 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1368,6 +1368,22 @@ static void format_corename(char *corename, const char *pattern, long signr)
        *out_ptr = 0;
 }
 
+static void zap_process(struct task_struct *start, int *ptraced)
+{
+       struct task_struct *t;
+
+       t = start;
+       do {
+               if (t != current && t->mm) {
+                       t->mm->core_waiters++;
+                       force_sig_specific(SIGKILL, t);
+                       if (unlikely(t->ptrace) &&
+                           unlikely(t->parent->mm == t->mm))
+                               *ptraced = 1;
+               }
+       } while ((t = next_thread(t)) != start);
+}
+
 static void zap_threads (struct mm_struct *mm)
 {
        struct task_struct *g, *p;
@@ -1385,16 +1401,16 @@ static void zap_threads (struct mm_struct *mm)
        }
 
        read_lock(&tasklist_lock);
-       do_each_thread(g,p)
-               if (mm == p->mm && p != tsk) {
-                       force_sig_specific(SIGKILL, p);
-                       mm->core_waiters++;
-                       if (unlikely(p->ptrace) &&
-                           unlikely(p->parent->mm == mm))
-                               traced = 1;
-               }
-       while_each_thread(g,p);
-
+       for_each_process(g) {
+               p = g;
+               do {
+                       if (p->mm) {
+                               if (p->mm == mm)
+                                       zap_process(p, &traced);
+                               break;
+                       }
+               } while ((p = next_thread(p)) != g);
+       }
        read_unlock(&tasklist_lock);
 
        if (unlikely(traced)) {