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>
diff --git a/kernel/signal.c b/kernel/signal.c
index f4db769..03d874e 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1727,7 +1727,7 @@
static int do_signal_stop(int signr)
{
struct signal_struct *sig = current->signal;
- int notify;
+ int notify = 0;
if (!sig->group_stop_count) {
struct task_struct *t;
@@ -1759,19 +1759,16 @@
* a group stop in progress and we are the last to stop, report
* to the parent. When ptraced, every thread reports itself.
*/
- notify = sig->group_stop_count == 1 ? CLD_STOPPED : 0;
- notify = tracehook_notify_jctl(notify, CLD_STOPPED);
- /*
- * tracehook_notify_jctl() can drop and reacquire siglock, so
- * we keep ->group_stop_count != 0 before the call. If SIGCONT
- * or SIGKILL comes in between ->group_stop_count == 0.
- */
- if (sig->group_stop_count) {
- if (!--sig->group_stop_count)
- sig->flags = SIGNAL_STOP_STOPPED;
- current->exit_code = sig->group_exit_code;
- __set_current_state(TASK_STOPPED);
+ if (!--sig->group_stop_count) {
+ sig->flags = SIGNAL_STOP_STOPPED;
+ notify = CLD_STOPPED;
}
+ if (task_ptrace(current))
+ notify = CLD_STOPPED;
+
+ current->exit_code = sig->group_exit_code;
+ __set_current_state(TASK_STOPPED);
+
spin_unlock_irq(¤t->sighand->siglock);
if (notify) {
@@ -1860,14 +1857,11 @@
signal->flags &= ~SIGNAL_CLD_MASK;
- why = tracehook_notify_jctl(why, CLD_CONTINUED);
spin_unlock_irq(&sighand->siglock);
- if (why) {
- read_lock(&tasklist_lock);
- do_notify_parent_cldstop(current->group_leader, why);
- read_unlock(&tasklist_lock);
- }
+ read_lock(&tasklist_lock);
+ do_notify_parent_cldstop(current->group_leader, why);
+ read_unlock(&tasklist_lock);
goto relock;
}
@@ -2034,7 +2028,7 @@
if (unlikely(tsk->signal->group_stop_count) &&
!--tsk->signal->group_stop_count) {
tsk->signal->flags = SIGNAL_STOP_STOPPED;
- group_stop = tracehook_notify_jctl(CLD_STOPPED, CLD_STOPPED);
+ group_stop = CLD_STOPPED;
}
out:
spin_unlock_irq(&tsk->sighand->siglock);