|
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 |
|