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" 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 --- devel/kernel/signal.c~simpler-signal-exit-concurrency-handling 2005-11-22 22:30:39.000000000 -0800 +++ devel-akpm/kernel/signal.c 2005-11-22 22:30:39.000000000 -0800 @@ -1101,18 +1101,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; _