aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index f4db76986ec..03d874e1058 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1727,7 +1727,7 @@ void ptrace_notify(int exit_code)
1727static int do_signal_stop(int signr) 1727static int do_signal_stop(int signr)
1728{ 1728{
1729 struct signal_struct *sig = current->signal; 1729 struct signal_struct *sig = current->signal;
1730 int notify; 1730 int notify = 0;
1731 1731
1732 if (!sig->group_stop_count) { 1732 if (!sig->group_stop_count) {
1733 struct task_struct *t; 1733 struct task_struct *t;
@@ -1759,19 +1759,16 @@ static int do_signal_stop(int signr)
1759 * a group stop in progress and we are the last to stop, report 1759 * a group stop in progress and we are the last to stop, report
1760 * to the parent. When ptraced, every thread reports itself. 1760 * to the parent. When ptraced, every thread reports itself.
1761 */ 1761 */
1762 notify = sig->group_stop_count == 1 ? CLD_STOPPED : 0; 1762 if (!--sig->group_stop_count) {
1763 notify = tracehook_notify_jctl(notify, CLD_STOPPED); 1763 sig->flags = SIGNAL_STOP_STOPPED;
1764 /* 1764 notify = CLD_STOPPED;
1765 * tracehook_notify_jctl() can drop and reacquire siglock, so
1766 * we keep ->group_stop_count != 0 before the call. If SIGCONT
1767 * or SIGKILL comes in between ->group_stop_count == 0.
1768 */
1769 if (sig->group_stop_count) {
1770 if (!--sig->group_stop_count)
1771 sig->flags = SIGNAL_STOP_STOPPED;
1772 current->exit_code = sig->group_exit_code;
1773 __set_current_state(TASK_STOPPED);
1774 } 1765 }
1766 if (task_ptrace(current))
1767 notify = CLD_STOPPED;
1768
1769 current->exit_code = sig->group_exit_code;
1770 __set_current_state(TASK_STOPPED);
1771
1775 spin_unlock_irq(&current->sighand->siglock); 1772 spin_unlock_irq(&current->sighand->siglock);
1776 1773
1777 if (notify) { 1774 if (notify) {
@@ -1860,14 +1857,11 @@ relock:
1860 1857
1861 signal->flags &= ~SIGNAL_CLD_MASK; 1858 signal->flags &= ~SIGNAL_CLD_MASK;
1862 1859
1863 why = tracehook_notify_jctl(why, CLD_CONTINUED);
1864 spin_unlock_irq(&sighand->siglock); 1860 spin_unlock_irq(&sighand->siglock);
1865 1861
1866 if (why) { 1862 read_lock(&tasklist_lock);
1867 read_lock(&tasklist_lock); 1863 do_notify_parent_cldstop(current->group_leader, why);
1868 do_notify_parent_cldstop(current->group_leader, why); 1864 read_unlock(&tasklist_lock);
1869 read_unlock(&tasklist_lock);
1870 }
1871 goto relock; 1865 goto relock;
1872 } 1866 }
1873 1867
@@ -2034,7 +2028,7 @@ void exit_signals(struct task_struct *tsk)
2034 if (unlikely(tsk->signal->group_stop_count) && 2028 if (unlikely(tsk->signal->group_stop_count) &&
2035 !--tsk->signal->group_stop_count) { 2029 !--tsk->signal->group_stop_count) {
2036 tsk->signal->flags = SIGNAL_STOP_STOPPED; 2030 tsk->signal->flags = SIGNAL_STOP_STOPPED;
2037 group_stop = tracehook_notify_jctl(CLD_STOPPED, CLD_STOPPED); 2031 group_stop = CLD_STOPPED;
2038 } 2032 }
2039out: 2033out:
2040 spin_unlock_irq(&tsk->sighand->siglock); 2034 spin_unlock_irq(&tsk->sighand->siglock);