On 06/30, Oleg Nesterov wrote: > > On 06/30, Nicholas Piggin wrote: > > > > My patch is what actually introduced this ugly > > bit test, but do we even need it at all? If we do then it's > > under-commented, I can't see it wouldn't be racy though. Can we just > > get rid of it entirely? > > But then we will need to move io_schedule() down, after test_and_set_bit(). > And we will have the same problem with task->state != RUNNING. Plus more > complications with "behavior == DROP".
may be someting like this for (;;) { int intr = 0; spin_lock_irq(&q->lock); if (signal_pending_state(state, current)) { /* see the comment in prepare_to_wait_event() */ list_del_init(&wait->entry); intr = 1; } else { if (likely(list_empty(&wait->entry))) { __add_wait_queue_entry_tail(q, wait); SetPageWaiters(page); } set_current_state(state); } spin_unlock_irq(&q->lock); if (behavior == EXCLUSIVE) { if (!test_and_set_bit_lock(bit_nr, &page->flags)) break; } else { int is_set = test_bit(bit_nr, &page->flags); if (behavior == DROP) put_page(page); if (!is_set) break; } if (intr) { ret = -EINTR; break; } io_schedule(); if (behavior == DROP) { /* * We can no longer safely access page->flags: * even if CONFIG_MEMORY_HOTREMOVE is not enabled, * there is a risk of waiting forever on a page reused * for something that keeps it locked indefinitely. * But best check for -EINTR before breaking. */ if (signal_pending_state(state, current)) ret = -EINTR; break; } } ? I dunno... Oleg.