Both utrace and ptrace can want the same thread to be quiescent, in this case its state is TASK_TRACED | TASK_UTRACED. And this also means that this task must not run unless both utrace and ptrace resume it. Change wake_up_quiescent(p, state) to do "p->state &= ~state" and return false unless there is no more "quiescent" bits in task->state. Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> --- kernel/signal.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index ba46eab..e06f795 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -701,11 +701,26 @@ void signal_wake_up(struct task_struct *t, int resume) kick_process(t); } +#define STATE_QUIESCENT (__TASK_STOPPED | __TASK_TRACED | __TASK_UTRACED) /* * wakes up the STOPPED/TRACED task, must be called with ->siglock held. */ int wake_up_quiescent(struct task_struct *p, unsigned int state) { + unsigned int quiescent = (p->state & STATE_QUIESCENT); + + WARN_ON(state & ~(STATE_QUIESCENT | TASK_INTERRUPTIBLE)); + + if (quiescent) { + state &= ~TASK_INTERRUPTIBLE; + if ((quiescent & ~state) != 0) { + p->state &= ~state; + WARN_ON(!(p->state & STATE_QUIESCENT)); + WARN_ON(!(p->state & TASK_WAKEKILL)); + return 0; + } + } + return wake_up_state(p, state); } -- 1.5.5.1 _______________________________________________ kernel mailing list kernel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/kernel