this patch is a port of Steven Rostedt's bitlock-removal patch to
BK-curr. It changes the ext3 code to use wait_on_bit_lock() on
&jbd_lock_bh_sleep, instead of the bitlock primitives.

Builds/boots/works fine on x86.

From: Steven Rostedt <[EMAIL PROTECTED]>
Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>

--- linux/fs/jbd/journal.c.orig
+++ linux/fs/jbd/journal.c
@@ -82,6 +82,17 @@ EXPORT_SYMBOL(journal_force_commit);
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+/*
+ * Used in the locking of the bh_state and bh_journalhead bit locks.
+ */
+int jbd_lock_bh_sleep(void *notused)
+{
+       schedule();
+       return 0;
+}
+#endif
+
 /*
  * Helper function used to manage commit timeouts
  */
--- linux/include/linux/jbd.h.orig
+++ linux/include/linux/jbd.h
@@ -65,7 +65,6 @@ extern int journal_enable_debug;
                }                                                       \
        } while (0)
 #else
-#define jbd_debug(f, a...)     /**/
 #endif
 
 extern void * __jbd_kmalloc (const char *where, size_t size, int flags, int 
retry);
@@ -324,34 +323,63 @@ static inline struct journal_head *bh2jh
        return bh->b_private;
 }
 
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+int jbd_lock_bh_sleep(void *notused);
+#endif
+
 static inline void jbd_lock_bh_state(struct buffer_head *bh)
 {
-       bit_spin_lock(BH_State, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       
wait_on_bit_lock(&bh->b_state,BH_State,&jbd_lock_bh_sleep,TASK_UNINTERRUPTIBLE);
+#endif
+       __acquire(bitlock);
 }
 
 static inline int jbd_trylock_bh_state(struct buffer_head *bh)
 {
-       return bit_spin_trylock(BH_State, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       if (test_and_set_bit(BH_State, &bh->b_state))
+               return 0;
+#endif
+       __acquire(bitlock);
+       return 1;
 }
 
 static inline int jbd_is_locked_bh_state(struct buffer_head *bh)
 {
-       return bit_spin_is_locked(BH_State, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       return test_bit(BH_State, &bh->b_state);
+#else
+       return 1;
+#endif
 }
 
 static inline void jbd_unlock_bh_state(struct buffer_head *bh)
 {
-       bit_spin_unlock(BH_State, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       clear_bit(BH_State, &bh->b_state);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&bh->b_state, BH_State);
+#endif
+       __release(bitlock);
 }
 
 static inline void jbd_lock_bh_journal_head(struct buffer_head *bh)
 {
-       bit_spin_lock(BH_JournalHead, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       
wait_on_bit_lock(&bh->b_state,BH_JournalHead,&jbd_lock_bh_sleep,TASK_UNINTERRUPTIBLE);
+#endif
+       __acquire(bitlock);
 }
 
 static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh)
 {
-       bit_spin_unlock(BH_JournalHead, &bh->b_state);
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || 
defined(CONFIG_PREEMPT)
+       clear_bit(BH_JournalHead, &bh->b_state);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&bh->b_state, BH_JournalHead);
+#endif
+       __release(bitlock);
 }
 
 struct jbd_revoke_table_s;
--- linux/include/linux/spinlock.h.orig
+++ linux/include/linux/spinlock.h
@@ -522,78 +522,6 @@ extern int _atomic_dec_and_lock(atomic_t
 
 #define atomic_dec_and_lock(atomic,lock) 
__cond_lock(_atomic_dec_and_lock(atomic,lock))
 
-/*
- *  bit-based spin_lock()
- *
- * Don't use this unless you really need to: spin_lock() and spin_unlock()
- * are significantly faster.
- */
-static inline void bit_spin_lock(int bitnum, unsigned long *addr)
-{
-       /*
-        * Assuming the lock is uncontended, this never enters
-        * the body of the outer loop. If it is contended, then
-        * within the inner loop a non-atomic test is used to
-        * busywait with less bus contention for a good time to
-        * attempt to acquire the lock bit.
-        */
-       preempt_disable();
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       while (test_and_set_bit(bitnum, addr)) {
-               while (test_bit(bitnum, addr)) {
-                       preempt_enable();
-                       cpu_relax();
-                       preempt_disable();
-               }
-       }
-#endif
-       __acquire(bitlock);
-}
-
-/*
- * Return true if it was acquired
- */
-static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
-{
-       preempt_disable();      
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       if (test_and_set_bit(bitnum, addr)) {
-               preempt_enable();
-               return 0;
-       }
-#endif
-       __acquire(bitlock);
-       return 1;
-}
-
-/*
- *  bit-based spin_unlock()
- */
-static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       BUG_ON(!test_bit(bitnum, addr));
-       smp_mb__before_clear_bit();
-       clear_bit(bitnum, addr);
-#endif
-       preempt_enable();
-       __release(bitlock);
-}
-
-/*
- * Return true if the lock is held.
- */
-static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       return test_bit(bitnum, addr);
-#elif defined CONFIG_PREEMPT
-       return preempt_count();
-#else
-       return 1;
-#endif
-}
-
 #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
 #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to