On Mon, Aug 04, 2014 at 12:30:26PM +0200, Peter Zijlstra wrote: > +long wait_woken(wait_queue_t *wait, unsigned mode, long timeout) > +{ > + set_current_state(mode); > + if (!(wait->flags & WQ_FLAG_WOKEN)) > + timeout = schedule_timeout(timeout); > + else > + wait->flags &= ~WQ_FLAG_WOKEN; I just noticed that poll_schedule_timeout() uses set_mb() for clearing its triggered variable. But I'm not entirely sure I see why.. > + __set_current_state(TASK_RUNNING); > + > + return timeout; > +} > +EXPORT_SYMBOL(wait_woken); > + > +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 expect 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(); > + wait->flags |= WQ_FLAG_WOKEN; > + > + return default_wake_function(wait, mode, sync, key); > +} > +EXPORT_SYMBOL(woken_wake_function); So possibly we could also use this for poll_schedule_timeout() and __pollwake().