aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-01-21 14:47:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-22 11:50:08 -0500
commit910ffdb18a6408e14febbb6e4b6840fd2c928c82 (patch)
tree258a215685f2ca2bb11dcd92582e0adafbd83f7b /kernel
parent9a9284153d965a57edc7162a8e57c14c97f3a935 (diff)
ptrace: introduce signal_wake_up_state() and ptrace_signal_wake_up()
Cleanup and preparation for the next change. signal_wake_up(resume => true) is overused. None of ptrace/jctl callers actually want to wakeup a TASK_WAKEKILL task, but they can't specify the necessary mask. Turn signal_wake_up() into signal_wake_up_state(state), reintroduce signal_wake_up() as a trivial helper, and add ptrace_signal_wake_up() which adds __TASK_TRACED. This way ptrace_signal_wake_up() can work "inside" ptrace_request() even if the tracee doesn't have the TASK_WAKEKILL bit set. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/ptrace.c8
-rw-r--r--kernel/signal.c14
2 files changed, 8 insertions, 14 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 612a56126851..62f7c2774b16 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -117,7 +117,7 @@ void __ptrace_unlink(struct task_struct *child)
117 * TASK_KILLABLE sleeps. 117 * TASK_KILLABLE sleeps.
118 */ 118 */
119 if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) 119 if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child))
120 signal_wake_up(child, task_is_traced(child)); 120 ptrace_signal_wake_up(child, true);
121 121
122 spin_unlock(&child->sighand->siglock); 122 spin_unlock(&child->sighand->siglock);
123} 123}
@@ -317,7 +317,7 @@ static int ptrace_attach(struct task_struct *task, long request,
317 */ 317 */
318 if (task_is_stopped(task) && 318 if (task_is_stopped(task) &&
319 task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) 319 task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING))
320 signal_wake_up(task, 1); 320 signal_wake_up_state(task, __TASK_STOPPED);
321 321
322 spin_unlock(&task->sighand->siglock); 322 spin_unlock(&task->sighand->siglock);
323 323
@@ -737,7 +737,7 @@ int ptrace_request(struct task_struct *child, long request,
737 * tracee into STOP. 737 * tracee into STOP.
738 */ 738 */
739 if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP))) 739 if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP)))
740 signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); 740 ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING);
741 741
742 unlock_task_sighand(child, &flags); 742 unlock_task_sighand(child, &flags);
743 ret = 0; 743 ret = 0;
@@ -763,7 +763,7 @@ int ptrace_request(struct task_struct *child, long request,
763 * start of this trap and now. Trigger re-trap. 763 * start of this trap and now. Trigger re-trap.
764 */ 764 */
765 if (child->jobctl & JOBCTL_TRAP_NOTIFY) 765 if (child->jobctl & JOBCTL_TRAP_NOTIFY)
766 signal_wake_up(child, true); 766 ptrace_signal_wake_up(child, true);
767 ret = 0; 767 ret = 0;
768 } 768 }
769 unlock_task_sighand(child, &flags); 769 unlock_task_sighand(child, &flags);
diff --git a/kernel/signal.c b/kernel/signal.c
index 53cd5c4d1172..6e97aa6fa32c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -680,23 +680,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
680 * No need to set need_resched since signal event passing 680 * No need to set need_resched since signal event passing
681 * goes through ->blocked 681 * goes through ->blocked
682 */ 682 */
683void signal_wake_up(struct task_struct *t, int resume) 683void signal_wake_up_state(struct task_struct *t, unsigned int state)
684{ 684{
685 unsigned int mask;
686
687 set_tsk_thread_flag(t, TIF_SIGPENDING); 685 set_tsk_thread_flag(t, TIF_SIGPENDING);
688
689 /* 686 /*
690 * For SIGKILL, we want to wake it up in the stopped/traced/killable 687 * TASK_WAKEKILL also means wake it up in the stopped/traced/killable
691 * case. We don't check t->state here because there is a race with it 688 * case. We don't check t->state here because there is a race with it
692 * executing another processor and just now entering stopped state. 689 * executing another processor and just now entering stopped state.
693 * By using wake_up_state, we ensure the process will wake up and 690 * By using wake_up_state, we ensure the process will wake up and
694 * handle its death signal. 691 * handle its death signal.
695 */ 692 */
696 mask = TASK_INTERRUPTIBLE; 693 if (!wake_up_state(t, state | TASK_INTERRUPTIBLE))
697 if (resume)
698 mask |= TASK_WAKEKILL;
699 if (!wake_up_state(t, mask))
700 kick_process(t); 694 kick_process(t);
701} 695}
702 696
@@ -844,7 +838,7 @@ static void ptrace_trap_notify(struct task_struct *t)
844 assert_spin_locked(&t->sighand->siglock); 838 assert_spin_locked(&t->sighand->siglock);
845 839
846 task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY); 840 task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY);
847 signal_wake_up(t, t->jobctl & JOBCTL_LISTENING); 841 ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING);
848} 842}
849 843
850/* 844/*