> For example, wait_consider_task(). Even some tracehooks, say, > tracehook_notify_death() need task_is_ptraced().
Not "some", just that one, right? So these are all really the same one thing: ptrace interfering with normal parent wait/SIGCHLD. In previous iterations, we had tracehook_inhibit_wait for hiding this in the tracehook layer. Then I decided to drop that and wait to revisit it until the final big ptrace clean-up. And now here we are! In the first utrace API, we had a NOREAP feature for this "cleanly" in the utrace layer, so any engine could say it wanted to interfere like ptrace. That was only there for ptrace and we really want nothing else new ever to be able to interfere like that. (An engine could delay death by using UTRACE_STOP at exit-tracing, and can get reap notification to track what the real parent does, but it can't hide death from the real parent or prevent reaping once death is upon us.) I'm still fairly confident that it would not be a useful general feature to let anybody ever foul up the real parent like ptrace does. So bottom line, I think it is probably fine and proper to have some manner of ptrace-only special-case for this. For the core kernel code, I think it is probably right to reintroduce tracehook_inhibit_wait. do_wait_thread: if (!task_detached(p) && !tracehook_inhibit_wait(p)) { int ret = wait_consider_task(wo, tsk, 0, p); That keeps it simple and clean there. The logic inside tracehook_{inhibit_wait,notify_death,notify_jctl} will hide the actual implementation. I'm inclined to avoid any more magic bits in utrace_flags, because I expect those bits to become useful and precious later. So I'd do: static inline bool tracehook_inhibit_wait(struct task_struct *task) { return task->utrace_flags && utrace_inhibit_wait(task); } and then utrace_inhibit_wait can look at a bit we keep in struct utrace or something like that. I think we might be able to get away with unlocked checks of that bit in wait, if we're sure that we'll do an extra wake_up_parent after detach or whatnot. OTOH, here's another idea. I think it might be the case that after being ptrace-attached and before any place that could matter (i.e. entering an exit_state or TASK_STOPPED) the tracee will go through some ->report_* callback to ptrace. In synchronous callbacks, it can do current->flags|= and then we could use a PF_* flag for this and keep the tracehook_inhibit_wait check extremely cheap. Thanks, Roland