Merge tag 'signal-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ebieder...
[sfrench/cifs-2.6.git] / kernel / exit.c
index 84021b24f79e3d1d2dc11fe70bf69cf620c7fc85..4f7424523bac9ae65745d69350217bfa17d56083 100644 (file)
@@ -733,11 +733,29 @@ static void check_stack_usage(void)
 static inline void check_stack_usage(void) {}
 #endif
 
+static void synchronize_group_exit(struct task_struct *tsk, long code)
+{
+       struct sighand_struct *sighand = tsk->sighand;
+       struct signal_struct *signal = tsk->signal;
+
+       spin_lock_irq(&sighand->siglock);
+       signal->quick_threads--;
+       if ((signal->quick_threads == 0) &&
+           !(signal->flags & SIGNAL_GROUP_EXIT)) {
+               signal->flags = SIGNAL_GROUP_EXIT;
+               signal->group_exit_code = code;
+               signal->group_stop_count = 0;
+       }
+       spin_unlock_irq(&sighand->siglock);
+}
+
 void __noreturn do_exit(long code)
 {
        struct task_struct *tsk = current;
        int group_dead;
 
+       synchronize_group_exit(tsk, code);
+
        WARN_ON(tsk->plug);
 
        kcov_task_exit(tsk);
@@ -905,7 +923,7 @@ do_group_exit(int exit_code)
                exit_code = sig->group_exit_code;
        else if (sig->group_exec_task)
                exit_code = 0;
-       else if (!thread_group_empty(current)) {
+       else {
                struct sighand_struct *const sighand = current->sighand;
 
                spin_lock_irq(&sighand->siglock);