aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-20 18:56:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-20 18:56:25 -0400
commitcf6ace16a3cd8b728fb0afa68368fd40bbeae19f (patch)
tree489c64380668e8c5a29d3f36f37554e4b081a647 /kernel/signal.c
parentacc11eab70591744369722280c9ce162a6193494 (diff)
parentd1e9ae47a0285d3f1699e8219ce50f656243b93f (diff)
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: signal: align __lock_task_sighand() irq disabling and RCU softirq,rcu: Inform RCU of irq_exit() activity sched: Add irq_{enter,exit}() to scheduler_ipi() rcu: protect __rcu_read_unlock() against scheduler-using irq handlers rcu: Streamline code produced by __rcu_read_unlock() rcu: Fix RCU_BOOST race handling current->rcu_read_unlock_special rcu: decrease rcu_report_exp_rnp coupling with scheduler
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index ff7678603328..415d85d6f6c6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1178,18 +1178,25 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
1178{ 1178{
1179 struct sighand_struct *sighand; 1179 struct sighand_struct *sighand;
1180 1180
1181 rcu_read_lock();
1182 for (;;) { 1181 for (;;) {
1182 local_irq_save(*flags);
1183 rcu_read_lock();
1183 sighand = rcu_dereference(tsk->sighand); 1184 sighand = rcu_dereference(tsk->sighand);
1184 if (unlikely(sighand == NULL)) 1185 if (unlikely(sighand == NULL)) {
1186 rcu_read_unlock();
1187 local_irq_restore(*flags);
1185 break; 1188 break;
1189 }
1186 1190
1187 spin_lock_irqsave(&sighand->siglock, *flags); 1191 spin_lock(&sighand->siglock);
1188 if (likely(sighand == tsk->sighand)) 1192 if (likely(sighand == tsk->sighand)) {
1193 rcu_read_unlock();
1189 break; 1194 break;
1190 spin_unlock_irqrestore(&sighand->siglock, *flags); 1195 }
1196 spin_unlock(&sighand->siglock);
1197 rcu_read_unlock();
1198 local_irq_restore(*flags);
1191 } 1199 }
1192 rcu_read_unlock();
1193 1200
1194 return sighand; 1201 return sighand;
1195} 1202}