diff options
| -rw-r--r-- | kernel/exit.c | 1 | ||||
| -rw-r--r-- | kernel/posix-timers.c | 2 | ||||
| -rw-r--r-- | kernel/signal.c | 14 |
3 files changed, 3 insertions, 14 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 43077732619b..3b25b182d2be 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -843,6 +843,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 843 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 843 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
| 844 | if (group_dead) { | 844 | if (group_dead) { |
| 845 | del_timer_sync(&tsk->signal->real_timer); | 845 | del_timer_sync(&tsk->signal->real_timer); |
| 846 | exit_itimers(tsk->signal); | ||
| 846 | acct_process(code); | 847 | acct_process(code); |
| 847 | } | 848 | } |
| 848 | exit_mm(tsk); | 849 | exit_mm(tsk); |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index b7b532acd9fc..dda3cda73c77 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -1157,7 +1157,7 @@ retry_delete: | |||
| 1157 | } | 1157 | } |
| 1158 | 1158 | ||
| 1159 | /* | 1159 | /* |
| 1160 | * This is called by __exit_signal, only when there are no more | 1160 | * This is called by do_exit or de_thread, only when there are no more |
| 1161 | * references to the shared signal_struct. | 1161 | * references to the shared signal_struct. |
| 1162 | */ | 1162 | */ |
| 1163 | void exit_itimers(struct signal_struct *sig) | 1163 | void exit_itimers(struct signal_struct *sig) |
diff --git a/kernel/signal.c b/kernel/signal.c index 50c992643771..f2b96b08fb44 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -397,20 +397,8 @@ void __exit_signal(struct task_struct *tsk) | |||
| 397 | flush_sigqueue(&tsk->pending); | 397 | flush_sigqueue(&tsk->pending); |
| 398 | if (sig) { | 398 | if (sig) { |
| 399 | /* | 399 | /* |
| 400 | * We are cleaning up the signal_struct here. We delayed | 400 | * We are cleaning up the signal_struct here. |
| 401 | * calling exit_itimers until after flush_sigqueue, just in | ||
| 402 | * case our thread-local pending queue contained a queued | ||
| 403 | * timer signal that would have been cleared in | ||
| 404 | * exit_itimers. When that called sigqueue_free, it would | ||
| 405 | * attempt to re-take the tasklist_lock and deadlock. This | ||
| 406 | * can never happen if we ensure that all queues the | ||
| 407 | * timer's signal might be queued on have been flushed | ||
| 408 | * first. The shared_pending queue, and our own pending | ||
| 409 | * queue are the only queues the timer could be on, since | ||
| 410 | * there are no other threads left in the group and timer | ||
| 411 | * signals are constrained to threads inside the group. | ||
| 412 | */ | 401 | */ |
| 413 | exit_itimers(sig); | ||
| 414 | exit_thread_group_keys(sig); | 402 | exit_thread_group_keys(sig); |
| 415 | kmem_cache_free(signal_cachep, sig); | 403 | kmem_cache_free(signal_cachep, sig); |
| 416 | } | 404 | } |
