> 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

Reply via email to