From: "Paul E. McKenney" Some simplification in checking signal delivery against concurrent exit. Instead of using get_task_struct_rcu(), which increments the task_struct reference count, check the reference count after acquiring sighand lock. Signed-off-by: "Paul E. McKenney" Cc: Ingo Molnar Cc: Roland McGrath Cc: Oleg Nesterov Signed-off-by: Andrew Morton --- kernel/signal.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff -puN kernel/signal.c~simpler-signal-exit-concurrency-handling kernel/signal.c --- 25/kernel/signal.c~simpler-signal-exit-concurrency-handling Fri Nov 4 14:32:01 2005 +++ 25-akpm/kernel/signal.c Fri Nov 4 14:32:01 2005 @@ -1110,18 +1110,19 @@ int group_send_sig_info(int sig, struct retry: ret = check_kill_permission(sig, info, p); - if (!ret && sig && (sp = p->sighand)) { - if (!get_task_struct_rcu(p)) - return -ESRCH; + if (!ret && sig && (sp = rcu_dereference(p->sighand))) { spin_lock_irqsave(&sp->siglock, flags); if (p->sighand != sp) { spin_unlock_irqrestore(&sp->siglock, flags); - put_task_struct(p); goto retry; } + if ((atomic_read(&sp->count) == 0) || + (atomic_read(&p->usage) == 0)) { + spin_unlock_irqrestore(&sp->siglock, flags); + return -ESRCH; + } ret = __group_send_sig_info(sig, info, p); spin_unlock_irqrestore(&sp->siglock, flags); - put_task_struct(p); } return ret; _