utrace_set_events/utrace_control && death/reap checks
Oleg Nesterov
oleg at redhat.com
Tue Mar 17 02:33:48 UTC 2009
On 03/15, Roland McGrath wrote:
>
> > utrace_set_events:
> >
> > (utrace->death && ((old_flags & ~events) & DEATH_EVENTS))
> >
> > "(old_flags & ~events) & DEATH_EVENTS)" means the caller tries to
> > clear DEATH/QUIESCE. Why this is not allowed? And why this is not
> > allowed _only_ when the target runs utrace_report_death()->REPORT()?
>
> This is specifically documented for -EALREADY, and in the DocBook section
> "Interlock with final callbacks". The idea is this:
Aha, I didn't know.
> > And I don't understand why do we need utrace->death at all.
> ...
> > it is only used by
> > utrace_control(UTRACE_DETACH).
> ...
> that it will (or it's already happening).
>
> utrace_control as the synchronizing step of
> asynchronous tear-down. If it returns 0, then report_death will not and it
> is safe to destroy data structures the callback code would use.
Yes, with your explanation above this is clear.
But can't we simplify this check a little bit?
utrace_control:
else if (unlikely(target->utrace_flags & DEATH_EVENTS) ||
unlikely(utrace->death)) {
return -EALREADY;
can't we just do
else if (unlikely(utrace->death)) {
return -EALREADY;
I guess I missed something, but can't understand why do we need to
check ->utrace_flags. We are going to call mark_engine_detached()
below which clears engine->flags, and we hold utrace->lock.
If utrace_flags & DEATH_EVENTS is true, the subsequent
utrace_report_death() must see engine->flags == 0 (it takes
utrace->lock before REPORT_CALLBACKS), so it won't call any
callback. Yes, it can play with engine itself, but this should
be safe because "struct utrace" has a reference to attached
engine.
No?
Oleg.
More information about the utrace-devel
mailing list