This patch fixes a problem when JFS is used with CONFIG_PREEMPT enabled.
There was a timing window that apparently didn't hurt us on SMP, but is
very easily hit with CONFIG_PREEMPT.
This patch can be pulled from bk://jfs.bkbits.net/linux-2.5
--------------------------------------------------------------
ChangeSet@1.663.4.1, 2002-10-02 13:25:44-05:00, shaggy@kleikamp.austin.ibm.com
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.)
fs/jfs/jfs_txnmgr.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
--------------------------------------------------------------
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c Wed Oct 2 14:33:43 2002
+++ b/fs/jfs/jfs_txnmgr.c Wed Oct 2 14:33:43 2002
@@ -2746,13 +2746,16 @@
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));
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/