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/

Reply via email to