walters / rpms / kernel

Forked from rpms/kernel 5 years ago
Clone
Kyle McMartin b889352
From 9bdade1bc13e547130d2629291758a579722e5d1 Mon Sep 17 00:00:00 2001
Kyle McMartin b889352
From: Oleg Nesterov <oleg@redhat.com>
Kyle McMartin b889352
Date: Fri, 5 Nov 2010 16:53:42 +0100
Kyle McMartin b889352
Subject: posix-cpu-timers: workaround to suppress the problems with mt exec
Kyle McMartin b889352
Kyle McMartin b889352
posix-cpu-timers.c correctly assumes that the dying process does
Kyle McMartin b889352
posix_cpu_timers_exit_group() and removes all !CPUCLOCK_PERTHREAD
Kyle McMartin b889352
timers from signal->cpu_timers list.
Kyle McMartin b889352
Kyle McMartin b889352
But, it also assumes that timer->it.cpu.task is always the group
Kyle McMartin b889352
leader, and thus the dead ->task means the dead thread group.
Kyle McMartin b889352
Kyle McMartin b889352
This is obviously not true after de_thread() changes the leader.
Kyle McMartin b889352
After that almost every posix_cpu_timer_ method has problems.
Kyle McMartin b889352
Kyle McMartin b889352
It is not simple to fix this bug correctly. First of all, I think
Kyle McMartin b889352
that timer->it.cpu should use struct pid instead of task_struct.
Kyle McMartin b889352
Also, the locking should be reworked completely. In particular,
Kyle McMartin b889352
tasklist_lock should not be used at all. This all needs a lot of
Kyle McMartin b889352
nontrivial and hard-to-test changes.
Kyle McMartin b889352
Kyle McMartin b889352
Change __exit_signal() to do posix_cpu_timers_exit_group() when
Kyle McMartin b889352
the old leader dies during exec. This is not the fix, just the
Kyle McMartin b889352
temporary hack to hide the problem for 2.6.37 and stable. IOW,
Kyle McMartin b889352
this is obviously wrong but this is what we currently have anyway:
Kyle McMartin b889352
cpu timers do not work after mt exec.
Kyle McMartin b889352
Kyle McMartin b889352
In theory this change adds another race. The exiting leader can
Kyle McMartin b889352
detach the timers which were attached to the new leader. However,
Kyle McMartin b889352
the window between de_thread() and release_task() is small, we
Kyle McMartin b889352
can pretend that sys_timer_create() was called before de_thread().
Kyle McMartin b889352
Kyle McMartin b889352
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Kyle McMartin b889352
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Kyle McMartin b889352
---
Kyle McMartin b889352
 kernel/exit.c |    8 ++++++++
Kyle McMartin b889352
 1 files changed, 8 insertions(+), 0 deletions(-)
Kyle McMartin b889352
Kyle McMartin b889352
diff --git a/kernel/exit.c b/kernel/exit.c
Kyle McMartin b889352
index 45102e9..02b7104 100644
Kyle McMartin b889352
--- a/kernel/exit.c
Kyle McMartin b889352
+++ b/kernel/exit.c
Kyle McMartin b889352
@@ -92,6 +92,14 @@ static void __exit_signal(struct task_struct *tsk)
Kyle McMartin b889352
 		posix_cpu_timers_exit_group(tsk);
Kyle McMartin b889352
 	else {
Kyle McMartin b889352
 		/*
Kyle McMartin b889352
+		 * This can only happen if the caller is de_thread().
Kyle McMartin b889352
+		 * FIXME: this is the temporary hack, we should teach
Kyle McMartin b889352
+		 * posix-cpu-timers to handle this case correctly.
Kyle McMartin b889352
+		 */
Kyle McMartin b889352
+		if (unlikely(has_group_leader_pid(tsk)))
Kyle McMartin b889352
+			posix_cpu_timers_exit_group(tsk);
Kyle McMartin b889352
+
Kyle McMartin b889352
+		/*
Kyle McMartin b889352
 		 * If there is any task waiting for the group exit
Kyle McMartin b889352
 		 * then notify it:
Kyle McMartin b889352
 		 */
Kyle McMartin b889352
-- 
Kyle McMartin b889352
1.7.3.2
Kyle McMartin b889352