Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4360690 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

wait: use EXIT_TRACE only if thread_group_leader(zombie)



wait_task_zombie() always uses EXIT_TRACE/ptrace_unlink() if
ptrace_reparented().  This is suboptimal and a bit confusing: we do not
need do_notify_parent(p) if !thread_group_leader(p) and in this case we
also do not need ptrace_unlink(), we can rely on ptrace_release_task().

Change wait_task_zombie() to check thread_group_leader() along with
ptrace_reparented() and simplify the final p->exit_state transition.

Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Tested-by: default avatarMichal Schmidt <mschmidt@redhat.com>
Cc: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Lennart Poettering <lpoetter@redhat.com>
Cc: Roland McGrath <roland@hack.frob.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent abd50b39
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -1040,7 +1040,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
	/*
	 * Move the task's state to DEAD/TRACE, only one thread can do this.
	 */
	state = traced ? EXIT_TRACE : EXIT_DEAD;
	state = traced && thread_group_leader(p) ? EXIT_TRACE : EXIT_DEAD;
	if (cmpxchg(&p->exit_state, EXIT_ZOMBIE, state) != EXIT_ZOMBIE)
		return 0;
	/*
@@ -1140,18 +1140,15 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
	if (!retval)
		retval = pid;

	if (traced) {
	if (state == EXIT_TRACE) {
		write_lock_irq(&tasklist_lock);
		/* We dropped tasklist, ptracer could die and untrace */
		ptrace_unlink(p);
		/*
		 * If this is not a sub-thread, notify the parent.
		 * If parent wants a zombie, don't release it now.
		 */
		state = EXIT_DEAD;
		if (thread_group_leader(p) &&
		    !do_notify_parent(p, p->exit_signal))

		/* If parent wants a zombie, don't release it now */
		state = EXIT_ZOMBIE;
		if (do_notify_parent(p, p->exit_signal))
			state = EXIT_DEAD;
		p->exit_state = state;
		write_unlock_irq(&tasklist_lock);
	}