Commit 676968a9 authored by Dave Kleikamp's avatar Dave Kleikamp

JFS: Releasing LOGGC_LOCK too early

In txLazyCommit, we are releasing log->gclock (LOGGC_LOCK) before
checking tblk->flag for tblkGC_LAZY.  For the case that tblkGC_LAZY
is not set, the user thread may release the tblk, and it may be
reused and the tblkGC_LAZY bit set again, between the time we release
the spinlock until we check the flag.  This is a lot to happen in an
SMP environment, but when CONFIG_PREEMPT is set, it is very easy to
see the problem.

The fix is to hold the spinlock until after we've checked the flag.

(Yes, I know the symbol names are ugly.)
parent 7570df54
......@@ -2746,13 +2746,16 @@ void txLazyCommit(struct tblock * tblk)
if (tblk->flag & tblkGC_READY)
wake_up(&tblk->gcwait); // LOGGC_WAKEUP
spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
/*
* Can't release log->gclock until we've tested tblk->flag
*/
if (tblk->flag & tblkGC_LAZY) {
spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
txUnlock(tblk);
tblk->flag &= ~tblkGC_LAZY;
txEnd(tblk - TxBlock); /* Convert back to tid */
}
} else
spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment