Commit 910ffdb18a6408e14febbb6e4b6840fd2c928c82
Committed by
Linus Torvalds
1 parent
9a9284153d
Exists in
master
and in
20 other branches
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>
Showing 3 changed files with 18 additions and 15 deletions Side-by-side Diff
include/linux/sched.h
... | ... | @@ -2714,7 +2714,16 @@ |
2714 | 2714 | extern void recalc_sigpending_and_wake(struct task_struct *t); |
2715 | 2715 | extern void recalc_sigpending(void); |
2716 | 2716 | |
2717 | -extern void signal_wake_up(struct task_struct *t, int resume_stopped); | |
2717 | +extern void signal_wake_up_state(struct task_struct *t, unsigned int state); | |
2718 | + | |
2719 | +static inline void signal_wake_up(struct task_struct *t, bool resume) | |
2720 | +{ | |
2721 | + signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0); | |
2722 | +} | |
2723 | +static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume) | |
2724 | +{ | |
2725 | + signal_wake_up_state(t, resume ? __TASK_TRACED : 0); | |
2726 | +} | |
2718 | 2727 | |
2719 | 2728 | /* |
2720 | 2729 | * Wrappers for p->thread_info->cpu access. No-op on UP. |
kernel/ptrace.c
... | ... | @@ -117,7 +117,7 @@ |
117 | 117 | * TASK_KILLABLE sleeps. |
118 | 118 | */ |
119 | 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 | 122 | spin_unlock(&child->sighand->siglock); |
123 | 123 | } |
... | ... | @@ -317,7 +317,7 @@ |
317 | 317 | */ |
318 | 318 | if (task_is_stopped(task) && |
319 | 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 | 322 | spin_unlock(&task->sighand->siglock); |
323 | 323 | |
... | ... | @@ -737,7 +737,7 @@ |
737 | 737 | * tracee into STOP. |
738 | 738 | */ |
739 | 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 | 742 | unlock_task_sighand(child, &flags); |
743 | 743 | ret = 0; |
... | ... | @@ -763,7 +763,7 @@ |
763 | 763 | * start of this trap and now. Trigger re-trap. |
764 | 764 | */ |
765 | 765 | if (child->jobctl & JOBCTL_TRAP_NOTIFY) |
766 | - signal_wake_up(child, true); | |
766 | + ptrace_signal_wake_up(child, true); | |
767 | 767 | ret = 0; |
768 | 768 | } |
769 | 769 | unlock_task_sighand(child, &flags); |
kernel/signal.c
... | ... | @@ -680,23 +680,17 @@ |
680 | 680 | * No need to set need_resched since signal event passing |
681 | 681 | * goes through ->blocked |
682 | 682 | */ |
683 | -void signal_wake_up(struct task_struct *t, int resume) | |
683 | +void signal_wake_up_state(struct task_struct *t, unsigned int state) | |
684 | 684 | { |
685 | - unsigned int mask; | |
686 | - | |
687 | 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 | 688 | * case. We don't check t->state here because there is a race with it |
692 | 689 | * executing another processor and just now entering stopped state. |
693 | 690 | * By using wake_up_state, we ensure the process will wake up and |
694 | 691 | * handle its death signal. |
695 | 692 | */ |
696 | - mask = TASK_INTERRUPTIBLE; | |
697 | - if (resume) | |
698 | - mask |= TASK_WAKEKILL; | |
699 | - if (!wake_up_state(t, mask)) | |
693 | + if (!wake_up_state(t, state | TASK_INTERRUPTIBLE)) | |
700 | 694 | kick_process(t); |
701 | 695 | } |
702 | 696 | |
... | ... | @@ -844,7 +838,7 @@ |
844 | 838 | assert_spin_locked(&t->sighand->siglock); |
845 | 839 | |
846 | 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 | /* |