diff options
-rw-r--r-- | kernel/signal.c | 24 |
1 files changed, 7 insertions, 17 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 0f865d67415d..8d8a940422a8 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1244,19 +1244,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, | |||
1244 | { | 1244 | { |
1245 | struct sighand_struct *sighand; | 1245 | struct sighand_struct *sighand; |
1246 | 1246 | ||
1247 | rcu_read_lock(); | ||
1247 | for (;;) { | 1248 | for (;;) { |
1248 | /* | ||
1249 | * Disable interrupts early to avoid deadlocks. | ||
1250 | * See rcu_read_unlock() comment header for details. | ||
1251 | */ | ||
1252 | local_irq_save(*flags); | ||
1253 | rcu_read_lock(); | ||
1254 | sighand = rcu_dereference(tsk->sighand); | 1249 | sighand = rcu_dereference(tsk->sighand); |
1255 | if (unlikely(sighand == NULL)) { | 1250 | if (unlikely(sighand == NULL)) |
1256 | rcu_read_unlock(); | ||
1257 | local_irq_restore(*flags); | ||
1258 | break; | 1251 | break; |
1259 | } | 1252 | |
1260 | /* | 1253 | /* |
1261 | * This sighand can be already freed and even reused, but | 1254 | * This sighand can be already freed and even reused, but |
1262 | * we rely on SLAB_TYPESAFE_BY_RCU and sighand_ctor() which | 1255 | * we rely on SLAB_TYPESAFE_BY_RCU and sighand_ctor() which |
@@ -1268,15 +1261,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, | |||
1268 | * __exit_signal(). In the latter case the next iteration | 1261 | * __exit_signal(). In the latter case the next iteration |
1269 | * must see ->sighand == NULL. | 1262 | * must see ->sighand == NULL. |
1270 | */ | 1263 | */ |
1271 | spin_lock(&sighand->siglock); | 1264 | spin_lock_irqsave(&sighand->siglock, *flags); |
1272 | if (likely(sighand == tsk->sighand)) { | 1265 | if (likely(sighand == tsk->sighand)) |
1273 | rcu_read_unlock(); | ||
1274 | break; | 1266 | break; |
1275 | } | 1267 | spin_unlock_irqrestore(&sighand->siglock, *flags); |
1276 | spin_unlock(&sighand->siglock); | ||
1277 | rcu_read_unlock(); | ||
1278 | local_irq_restore(*flags); | ||
1279 | } | 1268 | } |
1269 | rcu_read_unlock(); | ||
1280 | 1270 | ||
1281 | return sighand; | 1271 | return sighand; |
1282 | } | 1272 | } |