Re: [PATCH 3/7] barrier: a scalable synchonisation barrier

From: Oleg Nesterov
Date: Wed Jan 31 2007 - 16:31:28 EST


On 02/01, Oleg Nesterov wrote:
>
> +static inline void barrier_sync(struct barrier *b)
> +{
> + might_sleep();
> +
> + if (unlikely(atomic_read(&b->count))) {
> + DEFINE_WAIT(wait);
> + prepare_to_wait(&b->wait, &wait, TASK_UNINTERRUPTIBLE);
> + while (atomic_read(&b->count))
> + schedule();
> + finish_wait(&b->wait, &wait);
> + }
> +}
>
> This should be open-coded wait_event(), but wrong! With the scenario above this
> can hang forever! because the first wake_up removes the task from the &b->wait.

I am afraid I was not clear (as usual :). prepare_to_wait means autoremove_wake_function.
So, if barrier_unlock() wakes up the caller of barrier_sync(), it will be removed
from b->wait. If it goes to schedule() because another barrier_lock() incremented
b->count, we can't wake it via __wake_up(&b->wait, ...).

Oleg.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/