aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-03-23 05:37:00 -0400
committerTejun Heo <tj@kernel.org>2011-03-23 05:37:00 -0400
commitedf2ed153bcae52de70db00a98b0e81a5668e563 (patch)
tree78aa0207d78321778d6a504c8138d5bc9ef4b4b4 /kernel
parent71db5eb99c960e9c30e4b3ed04103c513b6251b5 (diff)
ptrace: Kill tracehook_notify_jctl()
tracehook_notify_jctl() aids in determining whether and what to report to the parent when a task is stopped or continued. The function also adds an extra requirement that siglock may be released across it, which is currently unused and quite difficult to satisfy in well-defined manner. As job control and the notifications are about to receive major overhaul, remove the tracehook and open code it. If ever necessary, let's factor it out after the overhaul. * Oleg spotted incorrect CLD_CONTINUED/STOPPED selection when ptraced. Fixed. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Roland McGrath <roland@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/signal.c34
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)
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);