<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/exit.c, branch v3.16</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v3.16</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v3.16'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2014-06-06T23:08:11Z</updated>
<entry>
<title>signals: mv {dis,}allow_signal() from sched.h/exit.c to signal.[ch]</title>
<updated>2014-06-06T23:08:11Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-06-06T21:36:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=0341729b4b832e753c5e745c6ba0e797f6198be0'/>
<id>urn:sha1:0341729b4b832e753c5e745c6ba0e797f6198be0</id>
<content type='text'>
Move the declaration/definition of allow_signal/disallow_signal to
signal.h/signal.c.  The new place is more logical and allows to use the
static helpers in signal.c (see the next changes).

While at it, make them return void and remove the valid_signal() check.
Nobody checks the returned value, and in-kernel users must not pass the
wrong signal number.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Cc: Peter Zijlstra &lt;peterz@infradead.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: David Woodhouse &lt;dwmw2@infradead.org&gt;
Cc: Frederic Weisbecker &lt;fweisbec@gmail.com&gt;
Cc: Geert Uytterhoeven &lt;geert@linux-m68k.org&gt;
Cc: Ingo Molnar &lt;mingo@kernel.org&gt;
Cc: Mathieu Desnoyers &lt;mathieu.desnoyers@efficios.com&gt;
Cc: Richard Weinberger &lt;richard@nod.at&gt;
Cc: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>memcg: optimize the "Search everything else" loop in mm_update_next_owner()</title>
<updated>2014-06-04T23:54:03Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-06-04T23:07:54Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=39af1765f1255b2bbadc3064e16270781abf24a1'/>
<id>urn:sha1:39af1765f1255b2bbadc3064e16270781abf24a1</id>
<content type='text'>
for_each_process_thread() is sub-optimal. All threads share the same
-&gt;mm, we can swicth to the next process once we found a thread with
-&gt;mm != NULL and -&gt;mm != mm.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Reviewed-by: Michal Hocko &lt;mhocko@suse.cz&gt;
Cc: Balbir Singh &lt;bsingharora@gmail.com&gt;
Cc: Johannes Weiner &lt;hannes@cmpxchg.org&gt;
Cc: KAMEZAWA Hiroyuki &lt;kamezawa.hiroyu@jp.fujitsu.com&gt;
Cc: Michal Hocko &lt;mhocko@suse.cz&gt;
Cc: Peter Chiang &lt;pchiang@nvidia.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>memcg: mm_update_next_owner() should skip kthreads</title>
<updated>2014-06-04T23:54:03Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-06-04T23:07:52Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f87fb599ae4d2a152a93f9821b94f3158146d097'/>
<id>urn:sha1:f87fb599ae4d2a152a93f9821b94f3158146d097</id>
<content type='text'>
"Search through everything else" in mm_update_next_owner() can hit a
kthread which adopted this "mm" via use_mm(), it should not be used as
mm-&gt;owner.  Add the PF_KTHREAD check.

While at it, change this code to use for_each_process_thread() instead
of deprecated do_each_thread/while_each_thread.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Reviewed-by: Michal Hocko &lt;mhocko@suse.cz&gt;
Cc: Balbir Singh &lt;bsingharora@gmail.com&gt;
Cc: Johannes Weiner &lt;hannes@cmpxchg.org&gt;
Cc: KAMEZAWA Hiroyuki &lt;kamezawa.hiroyu@jp.fujitsu.com&gt;
Cc: Michal Hocko &lt;mhocko@suse.cz&gt;
Cc: Peter Chiang &lt;pchiang@nvidia.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>memcg: kill CONFIG_MM_OWNER</title>
<updated>2014-06-04T23:54:01Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-06-04T23:07:34Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f98bafa06a28fdfdd5c49f820f4d6560f636fc46'/>
<id>urn:sha1:f98bafa06a28fdfdd5c49f820f4d6560f636fc46</id>
<content type='text'>
CONFIG_MM_OWNER makes no sense.  It is not user-selectable, it is only
selected by CONFIG_MEMCG automatically.  So we can kill this option in
init/Kconfig and do s/CONFIG_MM_OWNER/CONFIG_MEMCG/ globally.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Michal Hocko &lt;mhocko@suse.cz&gt;
Acked-by: Johannes Weiner &lt;hannes@cmpxchg.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: WSTOPPED|WCONTINUED doesn't work if a zombie leader is traced by another process</title>
<updated>2014-04-07T23:36:06Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:49Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=7c733eb3eac0e3d091aaf37c183d2175eeebfb2b'/>
<id>urn:sha1:7c733eb3eac0e3d091aaf37c183d2175eeebfb2b</id>
<content type='text'>
Even if the main thread is dead the process still can stop/continue.
However, if the leader is ptraced wait_consider_task(ptrace =&gt; false)
always skips wait_task_stopped/wait_task_continued, so WSTOPPED or
WCONTINUED can never work for the natural parent in this case.

Move the "A zombie ptracee is only visible to its ptracer" check into the
"if (!delay_group_leader(p))" block.  -&gt;notask_error is cleared by the
"fall through" code below.

This depends on the previous change, wait_task_stopped/continued must be
avoided if !delay_group_leader() and the tracer is -&gt;real_parent.
Otherwise WSTOPPED|WEXITED could wrongly report "stopped" when the child
is already dead (single-threaded or not).  If it is traced by another task
then the "stopped" state is fine until the debugger detaches and reveals a
zombie state.

Stupid test-case:

	void *tfunc(void *arg)
	{
		sleep(1);	// wait for zombie leader
		raise(SIGSTOP);
		exit(0x13);
		return NULL;
	}

	int run_child(void)
	{
		pthread_t thread;

		if (!fork()) {
			int tracee = getppid();

			assert(ptrace(PTRACE_ATTACH, tracee, 0,0) == 0);
			do
				ptrace(PTRACE_CONT, tracee, 0,0);
			while (wait(NULL) &gt; 0);

			return 0;
		}

		sleep(1);	// wait for PTRACE_ATTACH
		assert(pthread_create(&amp;thread, NULL, tfunc, NULL) == 0);
		pthread_exit(NULL);
	}

	int main(void)
	{
		int child, stat;

		child = fork();
		if (!child)
			return run_child();

		assert(child == waitpid(-1, &amp;stat, WSTOPPED));
		assert(stat == 0x137f);

		kill(child, SIGCONT);

		assert(child == waitpid(-1, &amp;stat, WCONTINUED));
		assert(stat == 0xffff);

		assert(child == waitpid(-1, &amp;stat, 0));
		assert(stat == 0x1300);

		return 0;
	}

Without this patch it hangs in waitpid(WSTOPPED), wait_task_stopped() is
never called.

Note: this doesn't fix all problems with a zombie delay_group_leader(),
WCONTINUED | WEXITED check is not exactly right.  debugger can't assume it
will be notified if another thread reaps the whole thread group.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: WSTOPPED|WCONTINUED hangs if a zombie child is traced by real_parent</title>
<updated>2014-04-07T23:36:06Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:47Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=377d75dafa07ee0da64223c9169f4e17b26c2b9a'/>
<id>urn:sha1:377d75dafa07ee0da64223c9169f4e17b26c2b9a</id>
<content type='text'>
"A zombie is only visible to its ptracer" logic in wait_consider_task()
is very wrong. Trivial test-case:

	#include &lt;unistd.h&gt;
	#include &lt;sys/ptrace.h&gt;
	#include &lt;sys/wait.h&gt;
	#include &lt;assert.h&gt;

	int main(void)
	{
		int child = fork();

		if (!child) {
			assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0);
			return 0x23;
		}

		assert(waitid(P_ALL, child, NULL, WEXITED | WNOWAIT) == 0);
		assert(waitid(P_ALL, 0, NULL, WSTOPPED) == -1);
		return 0;
	}

it hangs in waitpid(WSTOPPED) despite the fact it has a single zombie
child.  This is because wait_consider_task(ptrace =&gt; 0) sees p-&gt;ptrace and
cleares -&gt;notask_error assuming that the debugger should detach and notify
us.

Change wait_consider_task(ptrace =&gt; 0) to pretend that ptrace == T if the
child is traced by us.  This really simplifies the logic and allows us to
do more fixes, see the next changes.  This also hides the unwanted group
stop state automatically, we can remove another ptrace_reparented() check.

Unfortunately, this adds the following behavioural changes:

	1. Before this patch wait(WEXITED | __WNOTHREAD) does not reap
	   a natural child if it is traced by the caller's sub-thread.

	   Hopefully nobody will ever notice this change, and I think
	   that nobody should rely on this behaviour anyway.

	2. SIGNAL_STOP_CONTINUED is no longer hidden from debugger if
	   it is real parent.

	   While this change comes as a side effect, I think it is good
	   by itself. The group continued state can not be consumed by
	   another process in this case, it doesn't depend on ptrace,
	   it doesn't make sense to hide it from real parent.

	   Perhaps we should add the thread_group_leader() check before
	   wait_task_continued()? May be, but this shouldn't depend on
	   ptrace_reparented().

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: completely ignore the EXIT_DEAD tasks</title>
<updated>2014-04-07T23:36:06Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=b3ab03160dfaf8ab78d476b670de319f4c1a5685'/>
<id>urn:sha1:b3ab03160dfaf8ab78d476b670de319f4c1a5685</id>
<content type='text'>
Now that EXIT_DEAD is the terminal state it doesn't make sense to call
eligible_child() or security_task_wait() if the task is really dead.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Tested-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: use EXIT_TRACE only if thread_group_leader(zombie)</title>
<updated>2014-04-07T23:36:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:43Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=b436069059fede30ca31d4bf439cc86436ff5b1d'/>
<id>urn:sha1:b436069059fede30ca31d4bf439cc86436ff5b1d</id>
<content type='text'>
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-&gt;exit_state transition.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Tested-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: introduce EXIT_TRACE to avoid the racy EXIT_DEAD-&gt;EXIT_ZOMBIE transition</title>
<updated>2014-04-07T23:36:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=abd50b39e783e1b6c75c7534c37f1eb2d94a89cd'/>
<id>urn:sha1:abd50b39e783e1b6c75c7534c37f1eb2d94a89cd</id>
<content type='text'>
wait_task_zombie() first does EXIT_ZOMBIE-&gt;EXIT_DEAD transition and
drops tasklist_lock.  If this task is not the natural child and it is
traced, we change its state back to EXIT_ZOMBIE for -&gt;real_parent.

The last transition is racy, this is even documented in 50b8d257486a
"ptrace: partially fix the do_wait(WEXITED) vs EXIT_DEAD-&gt;EXIT_ZOMBIE
race".  wait_consider_task() tries to detect this transition and clear
-&gt;notask_error but we can't rely on ptrace_reparented(), debugger can
exit and do ptrace_unlink() before its sub-thread sets EXIT_ZOMBIE.

And there is another problem which were missed before: this transition
can also race with reparent_leader() which doesn't reset &gt;exit_signal if
EXIT_DEAD, assuming that this task must be reaped by someone else.  So
the tracee can be re-parented with -&gt;exit_signal != SIGCHLD, and if
/sbin/init doesn't use __WALL it becomes unreapable.  This was fixed by
the previous commit, but it was the temporary hack.

1. Add the new exit_state, EXIT_TRACE. It means that the task is the
   traced zombie, debugger is going to detach and notify its natural
   parent.

   This new state is actually EXIT_ZOMBIE | EXIT_DEAD. This way we
   can avoid the changes in proc/kgdb code, get_task_state() still
   reports "X (dead)" in this case.

   Note: with or without this change userspace can see Z -&gt; X -&gt; Z
   transition. Not really bad, but probably makes sense to fix.

2. Change wait_task_zombie() to use EXIT_TRACE instead of EXIT_DEAD
   if we need to notify the -&gt;real_parent.

3. Revert the previous hack in reparent_leader(), now that EXIT_DEAD
   is always the final state we can safely ignore such a task.

4. Change wait_consider_task() to check EXIT_TRACE separately and kill
   the racy and no longer needed ptrace_reparented() case.

   If ptrace == T an EXIT_TRACE thread should be simply ignored, the
   owner of this state is going to ptrace_unlink() this task. We can
   pretend that it was already removed from -&gt;ptraced list.

   Otherwise we should skip this thread too but clear -&gt;notask_error,
   we must be the natural parent and debugger is going to untrace and
   notify us. IOW, this doesn't differ from "EXIT_ZOMBIE &amp;&amp; p-&gt;ptrace"
   even if the task was already untraced.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Reported-by: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Reported-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Tested-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>wait: fix reparent_leader() vs EXIT_DEAD-&gt;EXIT_ZOMBIE race</title>
<updated>2014-04-07T23:36:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2014-04-07T22:38:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=dfccbb5e49a621c1b21a62527d61fc4305617aca'/>
<id>urn:sha1:dfccbb5e49a621c1b21a62527d61fc4305617aca</id>
<content type='text'>
wait_task_zombie() first does EXIT_ZOMBIE-&gt;EXIT_DEAD transition and
drops tasklist_lock.  If this task is not the natural child and it is
traced, we change its state back to EXIT_ZOMBIE for -&gt;real_parent.

The last transition is racy, this is even documented in 50b8d257486a
"ptrace: partially fix the do_wait(WEXITED) vs EXIT_DEAD-&gt;EXIT_ZOMBIE
race".  wait_consider_task() tries to detect this transition and clear
-&gt;notask_error but we can't rely on ptrace_reparented(), debugger can
exit and do ptrace_unlink() before its sub-thread sets EXIT_ZOMBIE.

And there is another problem which were missed before: this transition
can also race with reparent_leader() which doesn't reset &gt;exit_signal if
EXIT_DEAD, assuming that this task must be reaped by someone else.  So
the tracee can be re-parented with -&gt;exit_signal != SIGCHLD, and if
/sbin/init doesn't use __WALL it becomes unreapable.

Change reparent_leader() to update -&gt;exit_signal even if EXIT_DEAD.
Note: this is the simple temporary hack for -stable, it doesn't try to
solve all problems, it will be reverted by the next changes.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Reported-by: Jan Kratochvil &lt;jan.kratochvil@redhat.com&gt;
Reported-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Tested-by: Michal Schmidt &lt;mschmidt@redhat.com&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Lennart Poettering &lt;lpoetter@redhat.com&gt;
Cc: Roland McGrath &lt;roland@hack.frob.com&gt;
Cc: Tejun Heo &lt;tj@kernel.org&gt;
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
