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