Messages in this thread | | | Date | Wed, 22 Apr 2009 19:57:53 +0200 | From | Ingo Molnar <> | Subject | Re: [PATCH] Document that wake_up(), complete() and co. imply a full memory barrier |
| |
* David Howells <dhowells@redhat.com> wrote:
> +WAKE UP OF PROCESSES > +-------------------- > + > +An unlock, write memory barrier or a full memory barrier may be needed before a > +call to wake up another processes if the waker sets some state that the sleeper > +will need to see. > + > + complete(); > + wake_up(); > + wake_up_all(); > + wake_up_bit(); > + wake_up_interruptible(); > + wake_up_interruptible_all(); > + wake_up_interruptible_nr(); > + wake_up_interruptible_poll(); > + wake_up_interruptible_sync(); > + wake_up_interruptible_sync_poll(); > + wake_up_locked(); > + wake_up_locked_poll(); > + wake_up_nr(); > + wake_up_poll(); > + > +The sleeper may then need to interpolate a lock, read or full memory barrier > +before accessing that state.
Why would an unlock be needed before a call to wake_up() variants?
If a piece of code does:
wake_up*(&object->wq); ... spin_unlock(&object->lock);
that's perfectly race-free, as long as the wakee always starts with something like:
spin_lock(&object->lock); ...
I.e. waking up sooner than dropping the lock always OK (and it's a frequent operation). Your text seems to imply that a barrier is needed (or the unlock needs to happen first) but that's wrong i think.
The dangerous pattern is lockless code doing wakeups. But lockless code always has to use proper barriers or atomics anyway, and has to be aware of the fact that kernel primitives they call are not necessarily full memory barriers.
In fact i'd encourage to _not_ document try_to_lock() as a write barrier either - but rather have explicit barriers where they are needed. Then we could remove that barrier from try_to_wake_up() too ;-)
Hm?
Ingo
| |