diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2006-06-26 03:26:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:26 -0400 |
commit | aceecc041217b35df753d1ed6e25bd17c0c558d8 (patch) | |
tree | d78a9961bd8daecc31fc4720868b6f2a9a93aa94 | |
parent | 2ceb8693ef63ae3d154ce1a05d275f2bb20a5e4c (diff) |
[PATCH] coredump: optimize ->mm users traversal
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>
-rw-r--r-- | fs/exec.c | 36 |
1 files changed, 26 insertions, 10 deletions
@@ -1368,6 +1368,22 @@ static void format_corename(char *corename, const char *pattern, long signr) | |||
1368 | *out_ptr = 0; | 1368 | *out_ptr = 0; |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | static void zap_process(struct task_struct *start, int *ptraced) | ||
1372 | { | ||
1373 | struct task_struct *t; | ||
1374 | |||
1375 | t = start; | ||
1376 | do { | ||
1377 | if (t != current && t->mm) { | ||
1378 | t->mm->core_waiters++; | ||
1379 | force_sig_specific(SIGKILL, t); | ||
1380 | if (unlikely(t->ptrace) && | ||
1381 | unlikely(t->parent->mm == t->mm)) | ||
1382 | *ptraced = 1; | ||
1383 | } | ||
1384 | } while ((t = next_thread(t)) != start); | ||
1385 | } | ||
1386 | |||
1371 | static void zap_threads (struct mm_struct *mm) | 1387 | static void zap_threads (struct mm_struct *mm) |
1372 | { | 1388 | { |
1373 | struct task_struct *g, *p; | 1389 | struct task_struct *g, *p; |
@@ -1385,16 +1401,16 @@ static void zap_threads (struct mm_struct *mm) | |||
1385 | } | 1401 | } |
1386 | 1402 | ||
1387 | read_lock(&tasklist_lock); | 1403 | read_lock(&tasklist_lock); |
1388 | do_each_thread(g,p) | 1404 | for_each_process(g) { |
1389 | if (mm == p->mm && p != tsk) { | 1405 | p = g; |
1390 | force_sig_specific(SIGKILL, p); | 1406 | do { |
1391 | mm->core_waiters++; | 1407 | if (p->mm) { |
1392 | if (unlikely(p->ptrace) && | 1408 | if (p->mm == mm) |
1393 | unlikely(p->parent->mm == mm)) | 1409 | zap_process(p, &traced); |
1394 | traced = 1; | 1410 | break; |
1395 | } | 1411 | } |
1396 | while_each_thread(g,p); | 1412 | } while ((p = next_thread(p)) != g); |
1397 | 1413 | } | |
1398 | read_unlock(&tasklist_lock); | 1414 | read_unlock(&tasklist_lock); |
1399 | 1415 | ||
1400 | if (unlikely(traced)) { | 1416 | if (unlikely(traced)) { |