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: Tejun Heo <tj@kernel.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
This commit is contained in:
parent
755e276b33
commit
81be24b8cd
@ -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(¤t->sighand->siglock);
|
||||
|
Loading…
Reference in New Issue
Block a user