diff options
author | Sachin Nikam <snikam@nvidia.com> | 2013-03-06 19:12:15 +0530 |
---|---|---|
committer | Sachin Nikam <snikam@nvidia.com> | 2013-03-06 19:31:07 +0530 |
commit | d3dd6b4227fe3e59df0a55f679ec196e4ccb1e3a (patch) | |
tree | 0137a07ecab729a19cea68b671c88def5bf83a2d /kernel/signal.c | |
parent | bb36790494c382ec26250f351c8cea76613f0f02 (diff) | |
parent | 2713e2797a78a0fdda765bc5ad7fed41e94818ba (diff) |
Merge branch 'linux-3.4.35' into rel-17
Bug 1243631
Change-Id: I915826047b2e20f0ad0a7d75df295c6cbf6e5b0a
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 1dd48f7e7d6f..563b7711d234 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -677,23 +677,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) * No need to set need_resched since signal event passing * goes through ->blocked */ -void signal_wake_up(struct task_struct *t, int resume) +void signal_wake_up_state(struct task_struct *t, unsigned int state) { - unsigned int mask; - set_tsk_thread_flag(t, TIF_SIGPENDING); - /* - * For SIGKILL, we want to wake it up in the stopped/traced/killable + * TASK_WAKEKILL also means wake it up in the stopped/traced/killable * case. We don't check t->state here because there is a race with it * executing another processor and just now entering stopped state. * By using wake_up_state, we ensure the process will wake up and * handle its death signal. */ - mask = TASK_INTERRUPTIBLE; - if (resume) - mask |= TASK_WAKEKILL; - if (!wake_up_state(t, mask)) + if (!wake_up_state(t, state | TASK_INTERRUPTIBLE)) kick_process(t); } @@ -842,7 +836,7 @@ static void ptrace_trap_notify(struct task_struct *t) assert_spin_locked(&t->sighand->siglock); task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY); - signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); + ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); } /* @@ -1808,6 +1802,10 @@ static inline int may_ptrace_stop(void) * If SIGKILL was already sent before the caller unlocked * ->siglock we must see ->core_state != NULL. Otherwise it * is safe to enter schedule(). + * + * This is almost outdated, a task with the pending SIGKILL can't + * block in TASK_TRACED. But PTRACE_EVENT_EXIT can be reported + * after SIGKILL was already dequeued. */ if (unlikely(current->mm->core_state) && unlikely(current->mm == current->parent->mm)) @@ -1933,6 +1931,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) if (gstop_done) do_notify_parent_cldstop(current, false, why); + /* tasklist protects us from ptrace_freeze_traced() */ __set_current_state(TASK_RUNNING); if (clear_code) current->exit_code = 0; |