diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 43 |
1 files changed, 5 insertions, 38 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index ea90c34e9348..1117b28488c2 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1688,9 +1688,6 @@ static int do_signal_stop(int signr) | |||
1688 | struct signal_struct *sig = current->signal; | 1688 | struct signal_struct *sig = current->signal; |
1689 | int stop_count; | 1689 | int stop_count; |
1690 | 1690 | ||
1691 | if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) | ||
1692 | return 0; | ||
1693 | |||
1694 | if (sig->group_stop_count > 0) { | 1691 | if (sig->group_stop_count > 0) { |
1695 | /* | 1692 | /* |
1696 | * There is a group stop in progress. We don't need to | 1693 | * There is a group stop in progress. We don't need to |
@@ -1698,12 +1695,14 @@ static int do_signal_stop(int signr) | |||
1698 | */ | 1695 | */ |
1699 | stop_count = --sig->group_stop_count; | 1696 | stop_count = --sig->group_stop_count; |
1700 | } else { | 1697 | } else { |
1698 | struct task_struct *t; | ||
1699 | |||
1700 | if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) | ||
1701 | return 0; | ||
1701 | /* | 1702 | /* |
1702 | * There is no group stop already in progress. | 1703 | * There is no group stop already in progress. |
1703 | * We must initiate one now. | 1704 | * We must initiate one now. |
1704 | */ | 1705 | */ |
1705 | struct task_struct *t; | ||
1706 | |||
1707 | sig->group_exit_code = signr; | 1706 | sig->group_exit_code = signr; |
1708 | 1707 | ||
1709 | stop_count = 0; | 1708 | stop_count = 0; |
@@ -1731,38 +1730,6 @@ static int do_signal_stop(int signr) | |||
1731 | return 1; | 1730 | return 1; |
1732 | } | 1731 | } |
1733 | 1732 | ||
1734 | /* | ||
1735 | * Do appropriate magic when group_stop_count > 0. | ||
1736 | * We return nonzero if we stopped, after releasing the siglock. | ||
1737 | * We return zero if we still hold the siglock and should look | ||
1738 | * for another signal without checking group_stop_count again. | ||
1739 | */ | ||
1740 | static int handle_group_stop(void) | ||
1741 | { | ||
1742 | int stop_count; | ||
1743 | |||
1744 | if (current->signal->flags & SIGNAL_GROUP_EXIT) | ||
1745 | /* | ||
1746 | * Group stop is so another thread can do a core dump, | ||
1747 | * or else we are racing against a death signal. | ||
1748 | * Just punt the stop so we can get the next signal. | ||
1749 | */ | ||
1750 | return 0; | ||
1751 | |||
1752 | /* | ||
1753 | * There is a group stop in progress. We stop | ||
1754 | * without any associated signal being in our queue. | ||
1755 | */ | ||
1756 | stop_count = --current->signal->group_stop_count; | ||
1757 | if (stop_count == 0) | ||
1758 | current->signal->flags = SIGNAL_STOP_STOPPED; | ||
1759 | current->exit_code = current->signal->group_exit_code; | ||
1760 | set_current_state(TASK_STOPPED); | ||
1761 | spin_unlock_irq(¤t->sighand->siglock); | ||
1762 | finish_stop(stop_count); | ||
1763 | return 1; | ||
1764 | } | ||
1765 | |||
1766 | int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, | 1733 | int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, |
1767 | struct pt_regs *regs, void *cookie) | 1734 | struct pt_regs *regs, void *cookie) |
1768 | { | 1735 | { |
@@ -1777,7 +1744,7 @@ relock: | |||
1777 | struct k_sigaction *ka; | 1744 | struct k_sigaction *ka; |
1778 | 1745 | ||
1779 | if (unlikely(current->signal->group_stop_count > 0) && | 1746 | if (unlikely(current->signal->group_stop_count > 0) && |
1780 | handle_group_stop()) | 1747 | do_signal_stop(0)) |
1781 | goto relock; | 1748 | goto relock; |
1782 | 1749 | ||
1783 | signr = dequeue_signal(current, mask, info); | 1750 | signr = dequeue_signal(current, mask, info); |