bool checking_timer;
 };
 
+struct multiprocess_signals {
+       sigset_t signal;
+       struct hlist_node node;
+};
+
 /*
  * NOTE! "signal_struct" does not have its own
  * locking, because a shared signal_struct always
        /* shared signal handling: */
        struct sigpending       shared_pending;
 
+       /* For collecting multiprocess signals during fork */
+       struct hlist_head       multiprocess;
+
        /* thread group exit support */
        int                     group_exit_code;
        /* overloaded:
 
        init_waitqueue_head(&sig->wait_chldexit);
        sig->curr_target = tsk;
        init_sigpending(&sig->shared_pending);
+       INIT_HLIST_HEAD(&sig->multiprocess);
        seqlock_init(&sig->stats_lock);
        prev_cputime_init(&sig->prev_cputime);
 
 {
        int retval;
        struct task_struct *p;
+       struct multiprocess_signals delayed;
 
        /*
         * Don't allow sharing the root directory with processes in a different
                        return ERR_PTR(-EINVAL);
        }
 
+       /*
+        * Force any signals received before this point to be delivered
+        * before the fork happens.  Collect up signals sent to multiple
+        * processes that happen during the fork and delay them so that
+        * they appear to happen after the fork.
+        */
+       sigemptyset(&delayed.signal);
+       INIT_HLIST_NODE(&delayed.node);
+
+       spin_lock_irq(¤t->sighand->siglock);
+       if (!(clone_flags & CLONE_THREAD))
+               hlist_add_head(&delayed.node, ¤t->signal->multiprocess);
+       recalc_sigpending();
+       spin_unlock_irq(¤t->sighand->siglock);
+       retval = -ERESTARTNOINTR;
+       if (signal_pending(current))
+               goto fork_out;
+
        retval = -ENOMEM;
        p = dup_task_struct(current, node);
        if (!p)
                goto bad_fork_cancel_cgroup;
        }
 
-       if (!(clone_flags & CLONE_THREAD)) {
-               /*
-                * Process group and session signals need to be delivered to just the
-                * parent before the fork or both the parent and the child after the
-                * fork. Restart if a signal comes in before we add the new process to
-                * it's process group.
-                * A fatal signal pending means that current will exit, so the new
-                * thread can't slip out of an OOM kill (or normal SIGKILL).
-                */
-               recalc_sigpending();
-               if (signal_pending(current)) {
-                       retval = -ERESTARTNOINTR;
-                       goto bad_fork_cancel_cgroup;
-               }
-       }
-
 
        init_task_pid_links(p);
        if (likely(p->pid)) {
                                ns_of_pid(pid)->child_reaper = p;
                                p->signal->flags |= SIGNAL_UNKILLABLE;
                        }
-
+                       p->signal->shared_pending.signal = delayed.signal;
                        p->signal->tty = tty_kref_get(current->signal->tty);
                        /*
                         * Inherit has_child_subreaper flag under the same
                attach_pid(p, PIDTYPE_PID);
                nr_threads++;
        }
-
        total_forks++;
+       hlist_del_init(&delayed.node);
        spin_unlock(¤t->sighand->siglock);
        syscall_tracepoint_update(p);
        write_unlock_irq(&tasklist_lock);
        put_task_stack(p);
        free_task(p);
 fork_out:
+       spin_lock_irq(¤t->sighand->siglock);
+       hlist_del_init(&delayed.node);
+       spin_unlock_irq(¤t->sighand->siglock);
        return ERR_PTR(retval);
 }
 
 
 out_set:
        signalfd_notify(t, sig);
        sigaddset(&pending->signal, sig);
+
+       /* Let multiprocess signals appear after on-going forks */
+       if (type > PIDTYPE_TGID) {
+               struct multiprocess_signals *delayed;
+               hlist_for_each_entry(delayed, &t->signal->multiprocess, node) {
+                       sigset_t *signal = &delayed->signal;
+                       /* Can't queue both a stop and a continue signal */
+                       if (sig == SIGCONT)
+                               sigdelsetmask(signal, SIG_KERNEL_STOP_MASK);
+                       else if (sig_kernel_stop(sig))
+                               sigdelset(signal, SIGCONT);
+                       sigaddset(signal, sig);
+               }
+       }
+
        complete_signal(sig, t, type);
 ret:
        trace_signal_generate(sig, info, t, type != PIDTYPE_PID, result);