aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2010-05-26 17:43:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:46 -0400
commitd344193a05da89c97e965da2c5cbf687d7385eae (patch)
tree6267b68c31c4547f1749acd35d2a5bfaff919839 /fs/exec.c
parent09faef11df8c559a23e2405d123cb2683733a79a (diff)
exit: avoid sig->count in de_thread/__exit_signal synchronization
de_thread() and __exit_signal() use signal_struct->count/notify_count for synchronization. We can simplify the code and use ->notify_count only. Instead of comparing these two counters, we can change de_thread() to set ->notify_count = nr_of_sub_threads, then change __exit_signal() to dec-and-test this counter and notify group_exit_task. Note that __exit_signal() checks "notify_count > 0" just for symmetry with exit_notify(), we could just check it is != 0. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Roland McGrath <roland@redhat.com> Cc: Veaceslav Falico <vfalico@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.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 0c72d23ed0e2..e19de6a80339 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -768,7 +768,6 @@ static int de_thread(struct task_struct *tsk)
768 struct signal_struct *sig = tsk->signal; 768 struct signal_struct *sig = tsk->signal;
769 struct sighand_struct *oldsighand = tsk->sighand; 769 struct sighand_struct *oldsighand = tsk->sighand;
770 spinlock_t *lock = &oldsighand->siglock; 770 spinlock_t *lock = &oldsighand->siglock;
771 int count;
772 771
773 if (thread_group_empty(tsk)) 772 if (thread_group_empty(tsk))
774 goto no_thread_group; 773 goto no_thread_group;
@@ -785,13 +784,13 @@ static int de_thread(struct task_struct *tsk)
785 spin_unlock_irq(lock); 784 spin_unlock_irq(lock);
786 return -EAGAIN; 785 return -EAGAIN;
787 } 786 }
787
788 sig->group_exit_task = tsk; 788 sig->group_exit_task = tsk;
789 zap_other_threads(tsk); 789 sig->notify_count = zap_other_threads(tsk);
790 if (!thread_group_leader(tsk))
791 sig->notify_count--;
790 792
791 /* Account for the thread group leader hanging around: */ 793 while (sig->notify_count) {
792 count = thread_group_leader(tsk) ? 1 : 2;
793 sig->notify_count = count;
794 while (atomic_read(&sig->count) > count) {
795 __set_current_state(TASK_UNINTERRUPTIBLE); 794 __set_current_state(TASK_UNINTERRUPTIBLE);
796 spin_unlock_irq(lock); 795 spin_unlock_irq(lock);
797 schedule(); 796 schedule();