Exclusive waiters sleeping with LK_SLEEPFAIL on and using interruptible

sleeps/timeout may have left spourious lk_exslpfail counts on, so clean
it up even when accessing a shared queue acquisition, giving to
lk_exslpfail the value of 'upper limit'.
In the worst case scenario, infact (mixed
interruptible sleep / LK_SLEEPFAIL waiters) what may happen is that both
queues are awaken even if that's not necessary, but still no harm.

Reported by:	Lucius Windschuh <lwindschuh at googlemail dot com>
Reviewed by:	kib
Tested by:	pho, Lucius Windschuh <lwindschuh at googlemail dot com>
This commit is contained in:
Attilio Rao 2010-01-07 00:47:50 +00:00
parent 1feda9b418
commit 9dbf7a62f4

View File

@ -300,7 +300,14 @@ wakeupshlk(struct lock *lk, const char *file, int line)
}
} else {
MPASS(lk->lk_exslpfail == 0);
/*
* Exclusive waiters sleeping with LK_SLEEPFAIL on
* and using interruptible sleeps/timeout may have
* left spourious lk_exslpfail counts on, so clean
* it up anyway.
*/
lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
}
@ -959,7 +966,14 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
queue = SQ_SHARED_QUEUE;
}
} else {
MPASS(lk->lk_exslpfail == 0);
/*
* Exclusive waiters sleeping with LK_SLEEPFAIL
* on and using interruptible sleeps/timeout
* may have left spourious lk_exslpfail counts
* on, so clean it up anyway.
*/
lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
}
@ -1037,8 +1051,16 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
queue = SQ_EXCLUSIVE_QUEUE;
v &= ~LK_EXCLUSIVE_WAITERS;
} else {
/*
* Exclusive waiters sleeping with
* LK_SLEEPFAIL on and using
* interruptible sleeps/timeout may
* have left spourious lk_exslpfail
* counts on, so clean it up anyway.
*/
MPASS(v & LK_SHARED_WAITERS);
MPASS(lk->lk_exslpfail == 0);
lk->lk_exslpfail = 0;
queue = SQ_SHARED_QUEUE;
v &= ~LK_SHARED_WAITERS;
}