diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-07-20 20:59:26 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-07-20 20:59:26 +0200 |
commit | d1e9ae47a0285d3f1699e8219ce50f656243b93f (patch) | |
tree | 2f5a68b5ba1677bcd49ee759f09ffc5ccccb1455 /kernel/signal.c | |
parent | e6625fa48e6580a74b7e700efd7e6463e282810b (diff) | |
parent | a841796f11c90d53dbac773be56b04fbee8af272 (diff) |
Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu into core/urgent
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index ff767860332..415d85d6f6c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1178,18 +1178,25 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, { struct sighand_struct *sighand; - rcu_read_lock(); for (;;) { + local_irq_save(*flags); + rcu_read_lock(); sighand = rcu_dereference(tsk->sighand); - if (unlikely(sighand == NULL)) + if (unlikely(sighand == NULL)) { + rcu_read_unlock(); + local_irq_restore(*flags); break; + } - spin_lock_irqsave(&sighand->siglock, *flags); - if (likely(sighand == tsk->sighand)) + spin_lock(&sighand->siglock); + if (likely(sighand == tsk->sighand)) { + rcu_read_unlock(); break; - spin_unlock_irqrestore(&sighand->siglock, *flags); + } + spin_unlock(&sighand->siglock); + rcu_read_unlock(); + local_irq_restore(*flags); } - rcu_read_unlock(); return sighand; } |