NFS: Replace atomic_t variables in nfs_direct_req with a single spin lock
[linux-2.6/mini2440.git] / kernel / mutex-debug.h
blobfd384050acb1b7933ac414774cdf5aa4ae49fb48
1 /*
2 * Mutexes: blocking mutual exclusion locks
4 * started by Ingo Molnar:
6 * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
8 * This file contains mutex debugging related internal declarations,
9 * prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case.
10 * More details are in kernel/mutex-debug.c.
13 extern spinlock_t debug_mutex_lock;
14 extern struct list_head debug_mutex_held_locks;
15 extern int debug_mutex_on;
18 * In the debug case we carry the caller's instruction pointer into
19 * other functions, but we dont want the function argument overhead
20 * in the nondebug case - hence these macros:
22 #define __IP_DECL__ , unsigned long ip
23 #define __IP__ , ip
24 #define __RET_IP__ , (unsigned long)__builtin_return_address(0)
27 * This must be called with lock->wait_lock held.
29 extern void debug_mutex_set_owner(struct mutex *lock,
30 struct thread_info *new_owner __IP_DECL__);
32 static inline void debug_mutex_clear_owner(struct mutex *lock)
34 lock->owner = NULL;
37 extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);
38 extern void debug_mutex_wake_waiter(struct mutex *lock,
39 struct mutex_waiter *waiter);
40 extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
41 extern void debug_mutex_add_waiter(struct mutex *lock,
42 struct mutex_waiter *waiter,
43 struct thread_info *ti __IP_DECL__);
44 extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
45 struct thread_info *ti);
46 extern void debug_mutex_unlock(struct mutex *lock);
47 extern void debug_mutex_init(struct mutex *lock, const char *name);
49 #define debug_spin_lock(lock) \
50 do { \
51 local_irq_disable(); \
52 if (debug_mutex_on) \
53 spin_lock(lock); \
54 } while (0)
56 #define debug_spin_unlock(lock) \
57 do { \
58 if (debug_mutex_on) \
59 spin_unlock(lock); \
60 local_irq_enable(); \
61 preempt_check_resched(); \
62 } while (0)
64 #define debug_spin_lock_save(lock, flags) \
65 do { \
66 local_irq_save(flags); \
67 if (debug_mutex_on) \
68 spin_lock(lock); \
69 } while (0)
71 #define debug_spin_lock_restore(lock, flags) \
72 do { \
73 if (debug_mutex_on) \
74 spin_unlock(lock); \
75 local_irq_restore(flags); \
76 preempt_check_resched(); \
77 } while (0)
79 #define spin_lock_mutex(lock) \
80 do { \
81 struct mutex *l = container_of(lock, struct mutex, wait_lock); \
83 DEBUG_WARN_ON(in_interrupt()); \
84 debug_spin_lock(&debug_mutex_lock); \
85 spin_lock(lock); \
86 DEBUG_WARN_ON(l->magic != l); \
87 } while (0)
89 #define spin_unlock_mutex(lock) \
90 do { \
91 spin_unlock(lock); \
92 debug_spin_unlock(&debug_mutex_lock); \
93 } while (0)
95 #define DEBUG_OFF() \
96 do { \
97 if (debug_mutex_on) { \
98 debug_mutex_on = 0; \
99 console_verbose(); \
100 if (spin_is_locked(&debug_mutex_lock)) \
101 spin_unlock(&debug_mutex_lock); \
103 } while (0)
105 #define DEBUG_BUG() \
106 do { \
107 if (debug_mutex_on) { \
108 DEBUG_OFF(); \
109 BUG(); \
111 } while (0)
113 #define DEBUG_WARN_ON(c) \
114 do { \
115 if (unlikely(c && debug_mutex_on)) { \
116 DEBUG_OFF(); \
117 WARN_ON(1); \
119 } while (0)
121 # define DEBUG_BUG_ON(c) \
122 do { \
123 if (unlikely(c)) \
124 DEBUG_BUG(); \
125 } while (0)
127 #ifdef CONFIG_SMP
128 # define SMP_DEBUG_WARN_ON(c) DEBUG_WARN_ON(c)
129 # define SMP_DEBUG_BUG_ON(c) DEBUG_BUG_ON(c)
130 #else
131 # define SMP_DEBUG_WARN_ON(c) do { } while (0)
132 # define SMP_DEBUG_BUG_ON(c) do { } while (0)
133 #endif