Re: [PATCH] Document that wake_up(), complete() and co. imply a full memory barrier

Ingo Molnar
2009-04-22T17:58:37Z

* 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