On Mon, 19 Aug 2013 11:35:32 -0400 Steven Rostedt <rostedt@xxxxxxxxxxx> wrote: > From: Steven Rostedt <rostedt@xxxxxxxxxxx> > > There's a race condition with swait wakeups and adding to the list. The > __swait_wake() does a check for swait_head_has_waiters(), and if it is > empty it will exit without doing any wake ups. The problem is that the > check does not include any memory barriers before it makes a decision > to wake up or not. > > CPU0 CPU1 > ---- ---- > > condition = 1 > > load h->list (is empty) > raw_spin_lock(hlist->lock) > hlist_add(); > __set_current_state(); > raw_spin_unlock(hlist->lock) > swait_wake() > swait_head_has_waiters() > (sees h->list as empty and returns) > BTW, the race still exists if you move the raw_spin_unlock(hlist->lock) above to here. That is: swait_wake() swait_head_has_waiters() (sees h->list as empty and returns) raw_spin_unlock(hlist->lock) Maybe this will help to understand it more. -- Steve > check_condition (sees condition = 0) > > store condition = 1 > > schedule() > > Now the task on CPU1 has just missed its wakeup. By adding a memory > barrier before the list empty check, we fix the problem of miss seeing > the list not empty as well as pushing out the condition for the other > task to see. > > Reviewed-by: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html