utrace_reap(), like other reporting loops, sets/clears utrace->reporting, but this is not needed.
We already set ->ops = NULL, this means utrace_barrier() will never look at reporting. get_utrace_lock() can not succeed, it must return -ESRCH and utrace_barrier() just returns in this case. But more importantly, I think utrace_reap() never needs to synchronize with utrace_barrier(). Once we drop utrace->lock, any other caller which takes this lock must see both ->exit_state and utrace->reap. This means utrace_control() or utrace_set_events() which sets/clears REAP must not succeed. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/utrace.c | 9 --------- 1 file changed, 9 deletions(-) --- __UTRACE/kernel/utrace.c~2_NO_REPORTING 2009-09-06 15:06:27.000000000 +0200 +++ __UTRACE/kernel/utrace.c 2009-09-06 15:09:59.000000000 +0200 @@ -429,19 +429,10 @@ restart: if (!(flags & UTRACE_EVENT(REAP))) continue; - /* - * This synchronizes with utrace_barrier(). Since we - * need the utrace->lock here anyway (unlike the other - * reporting loops), we don't need any memory barrier - * as utrace_barrier() holds the lock. - */ - utrace->reporting = engine; spin_unlock(&utrace->lock); (*ops->report_reap)(engine, target); - utrace->reporting = NULL; - put_detached_list(&detached); spin_lock(&utrace->lock);