2.6.27-stable review patch. If anyone has any objections, please let us know.------------------

From: Johannes Weiner <hannes@cmpxchg.org>

commit 777c6c5f1f6e757ae49ecca2ed72d6b1f523c007 upstream.

With exclusive waiters, every process woken up through the wait queue mustensure that the next waiter down the line is woken when it has finished.

Interruptible waiters don't do that when aborting due to a signal. And ifan aborting waiter is concurrently woken up through the waitqueue, noonewill ever wake up the next waiter.

This has been observed with __wait_on_bit_lock() used bylock_page_killable(): the first contender on the queue was aborting whenthe actual lock holder woke it up concurrently. The aborted contenderdidn't acquire the lock and therefor never did an unlock followed bywaking up the next waiter.

Add abort_exclusive_wait() which removes the process' wait descriptor fromthe waitqueue, iff still queued, or wakes up the next waiter otherwise.It does so under the waitqueue lock. Racing with a wake up means theaborting process is either already woken (removed from the queue) and willwake up the next waiter, or it will remove itself from the queue and theconcurrent wake up will apply to the next waiter after it.

Use abort_exclusive_wait() in __wait_event_interruptible_exclusive() and__wait_on_bit_lock() when they were interrupted by other means than a wakeup through the queue.