On Thu, 3 May 2007, Nick Piggin wrote:
@@ -568,6 +570,11 @@ __lock_page (diff -p would tell us!)
{
DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
+ set_bit(PG_waiters, &page->flags);
+ if (unlikely(!TestSetPageLocked(page))) {
What happens if another cpu is coming through __lock_page at the
same time, did its set_bit, now finds PageLocked, and so proceeds
to the __wait_on_bit_lock? But this cpu now clears PG_waiters,
so this task's unlock_page won't wake the other?
You're right, we can't clear the bit here. Doubt it mattered much anyway?
Ah yes, that's a good easy answer. In fact, just remove this whole
test and block (we already tried TestSetPageLocked outside just a
short while ago, so this repeat won't often save anything).
BTW. I also forgot an smp_mb__after_clear_bit() before the wake_up_page
above... that barrier is in the slow path as well though, so it shouldn't
matter either.
I vaguely wondered how such barriers had managed to dissolve away,
but cranking my brain up to think about barriers takes far too long.