On 09/24, Peter Zijlstra wrote:
>
> There are a few places that call blocking primitives from wait loops,
> provide infrastructure to support this without the typical
> task_struct::state collision.
>
> We record the wakeup in wait_queue_t::flags which leaves
> task_struct::state free to be used by others.

Sorry for delay. FWIW,

Reviewed-by: Oleg Nesterov <[email protected]>

> +/*
> + * DEFINE_WAIT_FUNC(wait, woken_wait_func);
                             ^^^^^^^^^^^^^^^^
woken_wake_function ;)

> +int woken_wake_function(wait_queue_t *wait, unsigned mode, int sync, void 
> *key)
> +{
> +     /*
> +      * Although this function is called under waitqueue lock, LOCK
> +      * doesn't imply write barrier and the users expects write
> +      * barrier semantics on wakeup functions.  The following
> +      * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up()
> +      * and is paired with set_mb() in wait_woken().
> +      */
> +     smp_wmb(); /* C */
> +     wait->flags |= WQ_FLAG_WOKEN;

Perhaps it is just me, but I was a bit confused by the comment above wmb().
Afaics, it is not that "users expects write barrier semantics", just we
need to ensure that

        CONDITION = true;
        wait->flags |= WQ_FLAG_WOKEN;

can't be reordered (and this differs from smp_wmb() in try_to_wake_up()).
Otherwise we can obviously race with

        // wait_woken() -> set_mb()
        wait->flags &= ~WQ_FLAG_WOKEN;
        mb();

        if (CONDITION)
                break;

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