diff options
| -rw-r--r-- | kernel/signal.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index ad63109e413c..3169bed0b4d0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -1300,20 +1300,19 @@ struct sigqueue *sigqueue_alloc(void) | |||
| 1300 | void sigqueue_free(struct sigqueue *q) | 1300 | void sigqueue_free(struct sigqueue *q) |
| 1301 | { | 1301 | { |
| 1302 | unsigned long flags; | 1302 | unsigned long flags; |
| 1303 | spinlock_t *lock = ¤t->sighand->siglock; | ||
| 1304 | |||
| 1303 | BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); | 1305 | BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); |
| 1304 | /* | 1306 | /* |
| 1305 | * If the signal is still pending remove it from the | 1307 | * If the signal is still pending remove it from the |
| 1306 | * pending queue. | 1308 | * pending queue. We must hold ->siglock while testing |
| 1309 | * q->list to serialize with collect_signal(). | ||
| 1307 | */ | 1310 | */ |
| 1308 | if (unlikely(!list_empty(&q->list))) { | 1311 | spin_lock_irqsave(lock, flags); |
| 1309 | spinlock_t *lock = ¤t->sighand->siglock; | 1312 | if (!list_empty(&q->list)) |
| 1310 | read_lock(&tasklist_lock); | 1313 | list_del_init(&q->list); |
| 1311 | spin_lock_irqsave(lock, flags); | 1314 | spin_unlock_irqrestore(lock, flags); |
| 1312 | if (!list_empty(&q->list)) | 1315 | |
| 1313 | list_del_init(&q->list); | ||
| 1314 | spin_unlock_irqrestore(lock, flags); | ||
| 1315 | read_unlock(&tasklist_lock); | ||
| 1316 | } | ||
| 1317 | q->flags &= ~SIGQUEUE_PREALLOC; | 1316 | q->flags &= ~SIGQUEUE_PREALLOC; |
| 1318 | __sigqueue_free(q); | 1317 | __sigqueue_free(q); |
| 1319 | } | 1318 | } |
