diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-07-25 04:47:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:39 -0400 |
commit | 8cd9c249128a59e8e833d454a784b0cbd338d468 (patch) | |
tree | 54adf775bdd63fd55fc52b5ac70130a17058d866 /fs/exec.c | |
parent | 999d9fc1670bc082928b93b11d1f2e0e417d973c (diff) |
coredump: simplify core_state->nr_threads calculation
Change zap_process() to return int instead of incrementing
mm->core_state->nr_threads directly. Change zap_threads() to set
mm->core_state only on success.
This patch restores the original size of .text, and more importantly now
->nr_threads is used in two places only.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 33 |
1 files changed, 16 insertions, 17 deletions
@@ -1502,9 +1502,10 @@ out: | |||
1502 | return ispipe; | 1502 | return ispipe; |
1503 | } | 1503 | } |
1504 | 1504 | ||
1505 | static void zap_process(struct task_struct *start) | 1505 | static int zap_process(struct task_struct *start) |
1506 | { | 1506 | { |
1507 | struct task_struct *t; | 1507 | struct task_struct *t; |
1508 | int nr = 0; | ||
1508 | 1509 | ||
1509 | start->signal->flags = SIGNAL_GROUP_EXIT; | 1510 | start->signal->flags = SIGNAL_GROUP_EXIT; |
1510 | start->signal->group_stop_count = 0; | 1511 | start->signal->group_stop_count = 0; |
@@ -1512,31 +1513,33 @@ static void zap_process(struct task_struct *start) | |||
1512 | t = start; | 1513 | t = start; |
1513 | do { | 1514 | do { |
1514 | if (t != current && t->mm) { | 1515 | if (t != current && t->mm) { |
1515 | t->mm->core_state->nr_threads++; | ||
1516 | sigaddset(&t->pending.signal, SIGKILL); | 1516 | sigaddset(&t->pending.signal, SIGKILL); |
1517 | signal_wake_up(t, 1); | 1517 | signal_wake_up(t, 1); |
1518 | nr++; | ||
1518 | } | 1519 | } |
1519 | } while_each_thread(start, t); | 1520 | } while_each_thread(start, t); |
1521 | |||
1522 | return nr; | ||
1520 | } | 1523 | } |
1521 | 1524 | ||
1522 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | 1525 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, |
1523 | int exit_code) | 1526 | struct core_state *core_state, int exit_code) |
1524 | { | 1527 | { |
1525 | struct task_struct *g, *p; | 1528 | struct task_struct *g, *p; |
1526 | unsigned long flags; | 1529 | unsigned long flags; |
1527 | int err = -EAGAIN; | 1530 | int nr = -EAGAIN; |
1528 | 1531 | ||
1529 | spin_lock_irq(&tsk->sighand->siglock); | 1532 | spin_lock_irq(&tsk->sighand->siglock); |
1530 | if (!signal_group_exit(tsk->signal)) { | 1533 | if (!signal_group_exit(tsk->signal)) { |
1534 | mm->core_state = core_state; | ||
1531 | tsk->signal->group_exit_code = exit_code; | 1535 | tsk->signal->group_exit_code = exit_code; |
1532 | zap_process(tsk); | 1536 | nr = zap_process(tsk); |
1533 | err = 0; | ||
1534 | } | 1537 | } |
1535 | spin_unlock_irq(&tsk->sighand->siglock); | 1538 | spin_unlock_irq(&tsk->sighand->siglock); |
1536 | if (err) | 1539 | if (unlikely(nr < 0)) |
1537 | return err; | 1540 | return nr; |
1538 | 1541 | ||
1539 | if (atomic_read(&mm->mm_users) == mm->core_state->nr_threads + 1) | 1542 | if (atomic_read(&mm->mm_users) == nr + 1) |
1540 | goto done; | 1543 | goto done; |
1541 | /* | 1544 | /* |
1542 | * We should find and kill all tasks which use this mm, and we should | 1545 | * We should find and kill all tasks which use this mm, and we should |
@@ -1579,7 +1582,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
1579 | if (p->mm) { | 1582 | if (p->mm) { |
1580 | if (unlikely(p->mm == mm)) { | 1583 | if (unlikely(p->mm == mm)) { |
1581 | lock_task_sighand(p, &flags); | 1584 | lock_task_sighand(p, &flags); |
1582 | zap_process(p); | 1585 | nr += zap_process(p); |
1583 | unlock_task_sighand(p, &flags); | 1586 | unlock_task_sighand(p, &flags); |
1584 | } | 1587 | } |
1585 | break; | 1588 | break; |
@@ -1588,7 +1591,8 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
1588 | } | 1591 | } |
1589 | rcu_read_unlock(); | 1592 | rcu_read_unlock(); |
1590 | done: | 1593 | done: |
1591 | return mm->core_state->nr_threads; | 1594 | core_state->nr_threads = nr; |
1595 | return nr; | ||
1592 | } | 1596 | } |
1593 | 1597 | ||
1594 | static int coredump_wait(int exit_code) | 1598 | static int coredump_wait(int exit_code) |
@@ -1601,12 +1605,7 @@ static int coredump_wait(int exit_code) | |||
1601 | 1605 | ||
1602 | init_completion(&mm->core_done); | 1606 | init_completion(&mm->core_done); |
1603 | init_completion(&core_state.startup); | 1607 | init_completion(&core_state.startup); |
1604 | core_state.nr_threads = 0; | 1608 | core_waiters = zap_threads(tsk, mm, &core_state, exit_code); |
1605 | mm->core_state = &core_state; | ||
1606 | |||
1607 | core_waiters = zap_threads(tsk, mm, exit_code); | ||
1608 | if (core_waiters < 0) | ||
1609 | mm->core_state = NULL; | ||
1610 | up_write(&mm->mmap_sem); | 1609 | up_write(&mm->mmap_sem); |
1611 | 1610 | ||
1612 | if (unlikely(core_waiters < 0)) | 1611 | if (unlikely(core_waiters < 0)) |