Roland, but we forgot about UTRACE_DETACH. If we check ->utrace_flags != 0 before utrace_reap(), then utrace_reset() becomes unsafe: nothing protects task/utrace form disappearing once utrace_reset() sets ->utrace_flags == 0.
I am starting to think we are going to add too much subtle complications to avoid lock/unlock in release path :/ Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/utrace.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) --- __UTRACE/kernel/utrace.c~3_RESET_CAN_RACE_WITH_RELEASE 2009-09-08 22:21:57.000000000 +0200 +++ __UTRACE/kernel/utrace.c 2009-09-08 22:32:44.000000000 +0200 @@ -726,8 +726,6 @@ static bool utrace_reset(struct task_str clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE); } - task->utrace_flags = flags; - if (!flags) /* * No more engines, cleared out the utrace. @@ -740,7 +738,16 @@ static bool utrace_reset(struct task_str */ utrace_wakeup(task, utrace); + /* + * In theory spin_lock() doesn't imply rcu_read_lock(). + * Once we clear ->utrace_flags this task_struct can go away + * because tracehook_prepare_release_task() path does not take + * utrace->lock when ->utrace_flags == 0. + */ + rcu_read_lock(); + task->utrace_flags = flags; spin_unlock(&utrace->lock); + rcu_read_unlock(); put_detached_list(&detached);