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 [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/