> The problem is, utrace_control(DETACH) does nothing and returns > -EALREADY if utrace->death is set, this is not right. We can and > should detach in this case, we only should skip utrace_reset() to > avoid the race with utrace_report_death()->REPORT_CALLBACKS().
This behavior is the original (minimal) synchronization scheme from before we had utrace_barrier. See "Interlock with final callbacks" in Documentation/DocBook/utrace.tmpl. The expectation is that your report_death is going to clean up your ->data stuff and then return UTRACE_DETACH. If utrace_control returns -EALREADY, then you know that report_death is taking care of things. I'd imagined that you'd do something like: mutex_lock(stuff engine->data points to); mark in there that we are detaching; ret = utrace_control(task, engine, UTRACE_DETACH); if (ret == 0) { /* detached. tear our stuff down. */ ... return DONE; } else if (ret == -EALREADY) { /* report_death is running, i.e. waiting for our lock */ mutex_unlock(...); return DONE; } else ... Put another way, you can have told your report_death beforehand that it should return UTRACE_DETACH if it runs before your utrace_control call. Thanks, Roland