On 12/28, Oleg Nesterov wrote:
If nothing else, consider
int CONDITION; wait_queue_head_t WQ;
void wake(void) { CONDITION = 1; wake_up(WQ); }
void wait(void) { DEFINE_WAIT_FUNC(entry, woken_wake_function);
add_wait_queue(WQ, entry); if (!CONDITION) wait_woken(entry, ...); remove_wait_queue(WQ, entry);
}
this code is correct even if LOAD(CONDITION) can leak into the critical section in add_wait_queue(), so CPU running wait() can actually do
// add_wait_queue spin_lock(WQ->lock); LOAD(CONDITION); // false! list_add(entry, head); spin_unlock(WQ->lock); if (!false) // result of the LOAD above wait_woken(entry, ...);
Now suppose that another CPU executes wake() between LOAD(CONDITION) and list_add(entry, head). With your patch wait() will miss the event. The same for __pollwait(), I think...
No?
Even simpler,
void wait(void) { DEFINE_WAIT(entry);
__set_current_state(XXX); add_wait_queue(WQ, entry);
if (!CONDITION) schedule();
remove_wait_queue(WQ, entry); __set_current_state(TASK_RUNNING); }
This code is ugly but currently correct unless I am totally confused.
Oleg.