From: Tejun Heo Date: Thu, 2 Jun 2011 09:13:59 +0000 (+0200) Subject: ptrace: relocate set_current_state(TASK_TRACED) in ptrace_stop() X-Git-Tag: firefly_0821_release~3680^2~5000^2~35 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=81be24b8cdeb69e62f9d1b6b425fd9ffdd37f581;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Oleg Nesterov --- diff --git a/kernel/signal.c b/kernel/signal.c index ab6851c06461..62a6c3bb9f0d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -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);