Commit 06a101ca authored by Jens Axboe's avatar Jens Axboe
Browse files

exit: move core of do_wait() into helper



Rather than have a maze of gotos, put the actual logic in __do_wait()
and have do_wait() loop deal with waitqueue setup/teardown and whether
to call __do_wait() again.

No functional changes intended in this patch.

Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9d900d4e
Loading
Loading
Loading
Loading
+31 −20
Original line number Diff line number Diff line
@@ -1590,16 +1590,10 @@ static int do_wait_pid(struct wait_opts *wo)
	return 0;
}

static long do_wait(struct wait_opts *wo)
static long __do_wait(struct wait_opts *wo)
{
	int retval;
	long retval;

	trace_sched_process_wait(wo->wo_pid);

	init_waitqueue_func_entry(&wo->child_wait, child_wait_callback);
	wo->child_wait.private = current;
	add_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);
repeat:
	/*
	 * If there is nothing that can match our criteria, just get out.
	 * We will clear ->notask_error to zero if we see any child that
@@ -1611,24 +1605,23 @@ static long do_wait(struct wait_opts *wo)
	   (!wo->wo_pid || !pid_has_task(wo->wo_pid, wo->wo_type)))
		goto notask;

	set_current_state(TASK_INTERRUPTIBLE);
	read_lock(&tasklist_lock);

	if (wo->wo_type == PIDTYPE_PID) {
		retval = do_wait_pid(wo);
		if (retval)
			goto end;
			return retval;
	} else {
		struct task_struct *tsk = current;

		do {
			retval = do_wait_thread(wo, tsk);
			if (retval)
				goto end;
				return retval;

			retval = ptrace_do_wait(wo, tsk);
			if (retval)
				goto end;
				return retval;

			if (wo->wo_flags & __WNOTHREAD)
				break;
@@ -1638,14 +1631,32 @@ static long do_wait(struct wait_opts *wo)

notask:
	retval = wo->notask_error;
	if (!retval && !(wo->wo_flags & WNOHANG)) {
		retval = -ERESTARTSYS;
		if (!signal_pending(current)) {
			schedule();
			goto repeat;
		}
	if (!retval && !(wo->wo_flags & WNOHANG))
		return -ERESTARTSYS;

	return retval;
}
end:

static long do_wait(struct wait_opts *wo)
{
	int retval;

	trace_sched_process_wait(wo->wo_pid);

	init_waitqueue_func_entry(&wo->child_wait, child_wait_callback);
	wo->child_wait.private = current;
	add_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		retval = __do_wait(wo);
		if (retval != -ERESTARTSYS)
			break;
		if (signal_pending(current))
			break;
		schedule();
	} while (1);

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&current->signal->wait_chldexit, &wo->child_wait);
	return retval;