diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index f4db76986ec1..03d874e1058f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1727,7 +1727,7 @@ void ptrace_notify(int exit_code) | |||
1727 | static int do_signal_stop(int signr) | 1727 | static 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(¤t->sighand->siglock); | 1772 | spin_unlock_irq(¤t->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 | } |
2039 | out: | 2033 | out: |
2040 | spin_unlock_irq(&tsk->sighand->siglock); | 2034 | spin_unlock_irq(&tsk->sighand->siglock); |