static int do_signal_stop(int signr)
{
	struct signal_struct *sig = current->signal;

	if (!(current->group_stop & GROUP_STOP_PENDING)) {
		unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME;
		struct task_struct *t;

		/* signr will be recorded in task->group_stop for retries */
		WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK);

		if (!likely(current->group_stop & GROUP_STOP_DEQUEUED) ||
		    unlikely(signal_group_exit(sig)))
			return 0;
		/*
		 * There is no group stop already in progress.  We must
		 * initiate one now.
		 *
		 * While ptraced, a task may be resumed while group stop is
		 * still in effect and then receive a stop signal and
		 * initiate another group stop.  This deviates from the
		 * usual behavior as two consecutive stop signals can't
		 * cause two group stops when !ptraced.  That is why we
		 * also check !task_is_stopped(t) below.
		 *
		 * The condition can be distinguished by testing whether
		 * SIGNAL_STOP_STOPPED is already set.  Don't generate
		 * group_exit_code in such case.
		 *
		 * This is not necessary for SIGNAL_STOP_CONTINUED because
		 * an intervening stop signal is required to cause two
		 * continued events regardless of ptrace.
		 */
		if (!(sig->flags & SIGNAL_STOP_STOPPED))
			sig->group_exit_code = signr;

		current->group_stop &= ~GROUP_STOP_SIGMASK;
		current->group_stop |= signr | gstop;
		sig->group_stop_count = 1;
		for (t = next_thread(current); t != current;
		     t = next_thread(t)) {
			/*
			 * Setting state to TASK_STOPPED for a group
			 * stop is always done with the siglock held,
			 * so this check has no races.
			 */
			if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) {
				t->group_stop &= ~GROUP_STOP_SIGMASK;
				t->group_stop |= signr | gstop;
				sig->group_stop_count++;
				signal_wake_up(t, 0);
			}
		}
	}
retry:
	if (likely(!task_ptrace(current))) {
		int notify = 0;

		/*
		 * If there are no other threads in the group, or if there
		 * is a group stop in progress and we are the last to stop,
		 * report to the parent.
		 */
		if (task_participate_group_stop(current))
			notify = CLD_STOPPED;

		__set_current_state(TASK_STOPPED);
		spin_unlock_irq(&current->sighand->siglock);

		/*
		 * Notify the parent of the group stop completion.  Because
		 * we're not holding either the siglock or tasklist_lock
		 * here, ptracer may attach inbetween; however, this is for
		 * group stop and should always be delivered to the real
		 * parent of the group leader.  The new ptracer will get
		 * its notification when this task transitions into
		 * TASK_TRACED.
		 */
		if (notify) {
			read_lock(&tasklist_lock);
			do_notify_parent_cldstop(current, false, notify);
			read_unlock(&tasklist_lock);
		}

		/* Now we don't run again until woken by SIGCONT or SIGKILL */
		schedule();

		spin_lock_irq(&current->sighand->siglock);
	} else {
		ptrace_stop(current->group_stop & GROUP_STOP_SIGMASK,
			    CLD_STOPPED, 0, NULL);
		current->exit_code = 0;
	}

	/*
	 * GROUP_STOP_PENDING could be set if another group stop has
	 * started since being woken up or ptrace wants us to transit
	 * between TASK_STOPPED and TRACED.  Retry group stop.
	 */
	if (current->group_stop & GROUP_STOP_PENDING) {
		WARN_ON_ONCE(!(current->group_stop & GROUP_STOP_SIGMASK));
		goto retry;
	}

	/* PTRACE_ATTACH might have raced with task killing, clear trapping */
	task_clear_group_stop_trapping(current);

	spin_unlock_irq(&current->sighand->siglock);

	tracehook_finish_jctl();

	return 1;
}