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.
Unified · Split
| @@ -2714,7 +2714,16 @@ static inline void thread_group_cputime_init(struct signal_struct *sig) · 2713 unmodified lines | ||
| 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. |
| @@ -117,7 +117,7 @@ void __ptrace_unlink(struct task_struct *child) · 116 unmodified lines | ||
| 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 @@ static int ptrace_attach(struct task_struct *task, long request, · 193 unmodified lines | ||
| 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 @@ int ptrace_request(struct task_struct *child, long request, · 413 unmodified lines | ||
| 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 @@ int ptrace_request(struct task_struct *child, long request, · 19 unmodified lines | ||
| 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); |
| @@ -680,23 +680,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) · 679 unmodified lines | ||
| 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 @@ static void ptrace_trap_notify(struct task_struct *t) · 141 unmodified lines | ||
| 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 | /* |