diff options
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;  }  |