aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tracehook.h27
-rw-r--r--kernel/signal.c34
2 files changed, 14 insertions, 47 deletions
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 3a2e66d88a32..b073f3c8adc3 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -469,33 +469,6 @@ static inline int tracehook_get_signal(struct task_struct *task,
469} 469}
470 470
471/** 471/**
472 * tracehook_notify_jctl - report about job control stop/continue
473 * @notify: zero, %CLD_STOPPED or %CLD_CONTINUED
474 * @why: %CLD_STOPPED or %CLD_CONTINUED
475 *
476 * This is called when we might call do_notify_parent_cldstop().
477 *
478 * @notify is zero if we would not ordinarily send a %SIGCHLD,
479 * or is the %CLD_STOPPED or %CLD_CONTINUED .si_code for %SIGCHLD.
480 *
481 * @why is %CLD_STOPPED when about to stop for job control;
482 * we are already in %TASK_STOPPED state, about to call schedule().
483 * It might also be that we have just exited (check %PF_EXITING),
484 * but need to report that a group-wide stop is complete.
485 *
486 * @why is %CLD_CONTINUED when waking up after job control stop and
487 * ready to make a delayed @notify report.
488 *
489 * Return the %CLD_* value for %SIGCHLD, or zero to generate no signal.
490 *
491 * Called with the siglock held.
492 */
493static inline int tracehook_notify_jctl(int notify, int why)
494{
495 return notify ?: (current->ptrace & PT_PTRACED) ? why : 0;
496}
497
498/**
499 * tracehook_finish_jctl - report about return from job control stop 472 * tracehook_finish_jctl - report about return from job control stop
500 * 473 *
501 * This is called by do_signal_stop() after wakeup. 474 * This is called by do_signal_stop() after wakeup.
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)
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);