Commit 81be24b8 authored by Tejun Heo's avatar Tejun Heo Committed by Oleg Nesterov

ptrace: relocate set_current_state(TASK_TRACED) in ptrace_stop()

In ptrace_stop(), after arch hook is done, the task state and jobctl
bits are updated while holding siglock.  The ordering requirement
there is that TASK_TRACED is set before JOBCTL_TRAPPING is cleared to
prevent ptracer waiting on TRAPPING doesn't end up waking up TRACED is
actually set and sees TASK_RUNNING in wait(2).

Move set_current_state(TASK_TRACED) to the top of the block and
reorganize comments.  This makes the ordering more obvious
(TASK_TRACED before other updates) and helps future updates to group
stop participation.

This patch doesn't cause any functional change.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
parent 755e276b
......@@ -1732,6 +1732,18 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
return;
}
/*
* We're committing to trapping. TRACED should be visible before
* TRAPPING is cleared; otherwise, the tracer might fail do_wait().
* Also, transition to TRACED and updates to ->jobctl should be
* atomic with respect to siglock and should be done after the arch
* hook as siglock is released and regrabbed across it.
*/
set_current_state(TASK_TRACED);
current->last_siginfo = info;
current->exit_code = exit_code;
/*
* If @why is CLD_STOPPED, we're trapping to participate in a group
* stop. Do the bookkeeping. Note that if SIGCONT was delievered
......@@ -1742,21 +1754,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
gstop_done = task_participate_group_stop(current);
current->last_siginfo = info;
current->exit_code = exit_code;
/*
* TRACED should be visible before TRAPPING is cleared; otherwise,
* the tracer might fail do_wait().
*/
set_current_state(TASK_TRACED);
/*
* We're committing to trapping. Clearing JOBCTL_TRAPPING and
* transition to TASK_TRACED should be atomic with respect to
* siglock. This should be done after the arch hook as siglock is
* released and regrabbed across it.
*/
/* entering a trap, clear TRAPPING */
task_clear_jobctl_trapping(current);
spin_unlock_irq(&current->sighand->siglock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment