Messages in this thread Patch in this message | | | From | Tejun Heo <> | Subject | [PATCH 12/14] ptrace: reorganize __ptrace_unlink() and ptrace_untrace() | Date | Fri, 26 Nov 2010 11:49:27 +0100 |
| |
* Collapse ptrace_untrace() into __ptrace_unlink().
* Always do the whole unlinking inside siglock.
* Untracing is done before unlinking.
This is to prepare for further changes. As the whole unlinking/tracing is done inside both tasklist lock and siglock, the reordering doesn't cause any visible behavior difference.
Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Roland McGrath <roland@redhat.com> --- kernel/ptrace.c | 40 ++++++++++++++++++---------------------- 1 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 08b18f2..71141bf 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -38,45 +38,41 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) } /* - * Turn a tracing stop into a normal stop now, since with no tracer there - * would be no way to wake it up with SIGCONT or SIGKILL. If there was a - * signal sent that would resume the child, but didn't because it was in - * TASK_TRACED, resume it now. - * Requires that irqs be disabled. + * unptrace a task: move it back to its original parent and remove it + * from the ptrace list. + * + * Turn a tracing stop into a normal stop now, since with no tracer + * there would be no way to wake it up with SIGCONT or SIGKILL. If + * there was a signal sent that would resume the child, but didn't + * because it was in TASK_TRACED, resume it now. Requires that irqs + * be disabled. + * + * Must be called with the tasklist lock write-held. */ -static void ptrace_untrace(struct task_struct *child) +void __ptrace_unlink(struct task_struct *child) { + struct signal_struct *sig = child->signal; + + BUG_ON(!child->ptrace); + spin_lock(&child->sighand->siglock); + if (task_is_traced(child)) { /* * If group stop is completed or in progress, the task * should enter group stop. Set GROUP_STOP_PENDING * before kicking it. */ - if (child->signal->flags & SIGNAL_STOP_STOPPED || - child->signal->group_stop_count) + if (sig->flags & SIGNAL_STOP_STOPPED || sig->group_stop_count) child->group_stop |= GROUP_STOP_PENDING; signal_wake_up(child, 1); } - spin_unlock(&child->sighand->siglock); -} - -/* - * unptrace a task: move it back to its original parent and - * remove it from the ptrace list. - * - * Must be called with the tasklist lock write-held. - */ -void __ptrace_unlink(struct task_struct *child) -{ - BUG_ON(!child->ptrace); child->ptrace = 0; child->parent = child->real_parent; list_del_init(&child->ptrace_entry); - if (task_is_traced(child)) - ptrace_untrace(child); + spin_unlock(&child->sighand->siglock); } /* -- 1.7.1
| |