As Peter pointed out, this barrier is not needed. utrace_set_events()
and tracehook_report_death() can rely on tasklist_lock.

utrace_set_events() checks ->exit_state == 0 and adds DEATH_EVENTS
under tasklist_lock. After exit_notify() sets ->exit_state under
write_lock(tasklist) we must see the change in flags.

utrace_set_events() does not set _UTRACE_DEATH_EVENTS if ->exit_state
was already set by exit_notify(), and after we set ->exit_state under
write_lock(tasklist) we must see the change in ->utrace_flags.

Signed-off-by: Oleg Nesterov <o...@redhat.com>
---

 include/linux/tracehook.h |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

--- UTRACE-PTRACE/include/linux/tracehook.h~1_REPORT_DEATH_KILL_MB      
2009-11-18 21:16:23.000000000 +0100
+++ UTRACE-PTRACE/include/linux/tracehook.h     2009-12-12 16:32:39.000000000 
+0100
@@ -626,17 +626,12 @@ static inline void tracehook_report_deat
                                          int group_dead)
 {
        /*
-        * This barrier ensures that our caller's setting of
-        * @task->exit_state precedes checking @task->utrace_flags here.
         * If utrace_set_events() was just called to enable
         * UTRACE_EVENT(DEATH), then we are obliged to call
         * utrace_report_death() and not miss it.  utrace_set_events()
-        * uses tasklist_lock to synchronize enabling the bit with the
-        * actual change to @task->exit_state, but we need this barrier
-        * to be sure we see a flags change made just before our caller
-        * took the tasklist_lock.
+        * checks @task->exit_state under tasklist_lock to synchronize
+        * with exit_notify(), the caller.
         */
-       smp_mb();
        if (task_utrace_flags(task) & _UTRACE_DEATH_EVENTS)
                utrace_report_death(task, death_cookie, group_dead, signal);
 }

Reply via email to