aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-06-02 05:13:59 -0400
committerOleg Nesterov <oleg@redhat.com>2011-06-04 12:17:10 -0400
commit81be24b8cdeb69e62f9d1b6b425fd9ffdd37f581 (patch)
tree63afd141fdb380c7b00a01a2080ace6bcc232386 /kernel/signal.c
parent755e276b3326f300585435d2f3876e66e248c476 (diff)
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>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index ab6851c06461..62a6c3bb9f0d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1733,6 +1733,18 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1733 } 1733 }
1734 1734
1735 /* 1735 /*
1736 * We're committing to trapping. TRACED should be visible before
1737 * TRAPPING is cleared; otherwise, the tracer might fail do_wait().
1738 * Also, transition to TRACED and updates to ->jobctl should be
1739 * atomic with respect to siglock and should be done after the arch
1740 * hook as siglock is released and regrabbed across it.
1741 */
1742 set_current_state(TASK_TRACED);
1743
1744 current->last_siginfo = info;
1745 current->exit_code = exit_code;
1746
1747 /*
1736 * If @why is CLD_STOPPED, we're trapping to participate in a group 1748 * If @why is CLD_STOPPED, we're trapping to participate in a group
1737 * stop. Do the bookkeeping. Note that if SIGCONT was delievered 1749 * stop. Do the bookkeeping. Note that if SIGCONT was delievered
1738 * while siglock was released for the arch hook, PENDING could be 1750 * while siglock was released for the arch hook, PENDING could be
@@ -1742,21 +1754,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1742 if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING)) 1754 if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
1743 gstop_done = task_participate_group_stop(current); 1755 gstop_done = task_participate_group_stop(current);
1744 1756
1745 current->last_siginfo = info; 1757 /* entering a trap, clear TRAPPING */
1746 current->exit_code = exit_code;
1747
1748 /*
1749 * TRACED should be visible before TRAPPING is cleared; otherwise,
1750 * the tracer might fail do_wait().
1751 */
1752 set_current_state(TASK_TRACED);
1753
1754 /*
1755 * We're committing to trapping. Clearing JOBCTL_TRAPPING and
1756 * transition to TASK_TRACED should be atomic with respect to
1757 * siglock. This should be done after the arch hook as siglock is
1758 * released and regrabbed across it.
1759 */
1760 task_clear_jobctl_trapping(current); 1758 task_clear_jobctl_trapping(current);
1761 1759
1762 spin_unlock_irq(&current->sighand->siglock); 1760 spin_unlock_irq(&current->sighand->siglock);