linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / kernel / mutex-debug.h
index babfbdf..fd38405 100644 (file)
  * More details are in kernel/mutex-debug.c.
  */
 
+extern spinlock_t debug_mutex_lock;
+extern struct list_head debug_mutex_held_locks;
+extern int debug_mutex_on;
+
+/*
+ * In the debug case we carry the caller's instruction pointer into
+ * other functions, but we dont want the function argument overhead
+ * in the nondebug case - hence these macros:
+ */
+#define __IP_DECL__            , unsigned long ip
+#define __IP__                 , ip
+#define __RET_IP__             , (unsigned long)__builtin_return_address(0)
+
 /*
  * This must be called with lock->wait_lock held.
  */
-extern void
-debug_mutex_set_owner(struct mutex *lock, struct thread_info *new_owner);
+extern void debug_mutex_set_owner(struct mutex *lock,
+                                 struct thread_info *new_owner __IP_DECL__);
 
 static inline void debug_mutex_clear_owner(struct mutex *lock)
 {
        lock->owner = NULL;
 }
 
-extern void debug_mutex_lock_common(struct mutex *lock,
-                                   struct mutex_waiter *waiter);
+extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);
 extern void debug_mutex_wake_waiter(struct mutex *lock,
                                    struct mutex_waiter *waiter);
 extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
 extern void debug_mutex_add_waiter(struct mutex *lock,
                                   struct mutex_waiter *waiter,
-                                  struct thread_info *ti);
+                                  struct thread_info *ti __IP_DECL__);
 extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
                                struct thread_info *ti);
 extern void debug_mutex_unlock(struct mutex *lock);
-extern void debug_mutex_init(struct mutex *lock, const char *name,
-                            struct lock_class_key *key);
+extern void debug_mutex_init(struct mutex *lock, const char *name);
 
-#define spin_lock_mutex(lock, flags)                   \
+#define debug_spin_lock(lock)                          \
+       do {                                            \
+               local_irq_disable();                    \
+               if (debug_mutex_on)                     \
+                       spin_lock(lock);                \
+       } while (0)
+
+#define debug_spin_unlock(lock)                                \
+       do {                                            \
+               if (debug_mutex_on)                     \
+                       spin_unlock(lock);              \
+               local_irq_enable();                     \
+               preempt_check_resched();                \
+       } while (0)
+
+#define debug_spin_lock_save(lock, flags)              \
        do {                                            \
-               struct mutex *l = container_of(lock, struct mutex, wait_lock); \
-                                                       \
-               DEBUG_LOCKS_WARN_ON(in_interrupt());    \
                local_irq_save(flags);                  \
-               __raw_spin_lock(&(lock)->raw_lock);     \
-               DEBUG_LOCKS_WARN_ON(l->magic != l);     \
+               if (debug_mutex_on)                     \
+                       spin_lock(lock);                \
        } while (0)
 
-#define spin_unlock_mutex(lock, flags)                 \
+#define debug_spin_lock_restore(lock, flags)           \
        do {                                            \
-               __raw_spin_unlock(&(lock)->raw_lock);   \
+               if (debug_mutex_on)                     \
+                       spin_unlock(lock);              \
                local_irq_restore(flags);               \
                preempt_check_resched();                \
        } while (0)
+
+#define spin_lock_mutex(lock)                          \
+       do {                                            \
+               struct mutex *l = container_of(lock, struct mutex, wait_lock); \
+                                                       \
+               DEBUG_WARN_ON(in_interrupt());          \
+               debug_spin_lock(&debug_mutex_lock);     \
+               spin_lock(lock);                        \
+               DEBUG_WARN_ON(l->magic != l);           \
+       } while (0)
+
+#define spin_unlock_mutex(lock)                                \
+       do {                                            \
+               spin_unlock(lock);                      \
+               debug_spin_unlock(&debug_mutex_lock);   \
+       } while (0)
+
+#define DEBUG_OFF()                                    \
+do {                                                   \
+       if (debug_mutex_on) {                           \
+               debug_mutex_on = 0;                     \
+               console_verbose();                      \
+               if (spin_is_locked(&debug_mutex_lock))  \
+                       spin_unlock(&debug_mutex_lock); \
+       }                                               \
+} while (0)
+
+#define DEBUG_BUG()                                    \
+do {                                                   \
+       if (debug_mutex_on) {                           \
+               DEBUG_OFF();                            \
+               BUG();                                  \
+       }                                               \
+} while (0)
+
+#define DEBUG_WARN_ON(c)                               \
+do {                                                   \
+       if (unlikely(c && debug_mutex_on)) {            \
+               DEBUG_OFF();                            \
+               WARN_ON(1);                             \
+       }                                               \
+} while (0)
+
+# define DEBUG_BUG_ON(c)                               \
+do {                                                   \
+       if (unlikely(c))                                \
+               DEBUG_BUG();                            \
+} while (0)
+
+#ifdef CONFIG_SMP
+# define SMP_DEBUG_WARN_ON(c)                  DEBUG_WARN_ON(c)
+# define SMP_DEBUG_BUG_ON(c)                   DEBUG_BUG_ON(c)
+#else
+# define SMP_DEBUG_WARN_ON(c)                  do { } while (0)
+# define SMP_DEBUG_BUG_ON(c)                   do { } while (0)
+#endif
+