[PATCH] work around ppc64 bootup bug by making mutex-debugging save/restore irqs
[safe/jmp/linux-2.6] / kernel / mutex-debug.h
1 /*
2  * Mutexes: blocking mutual exclusion locks
3  *
4  * started by Ingo Molnar:
5  *
6  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
7  *
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.
11  */
12
13 extern spinlock_t debug_mutex_lock;
14 extern struct list_head debug_mutex_held_locks;
15 extern int debug_mutex_on;
16
17 /*
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:
21  */
22 #define __IP_DECL__             , unsigned long ip
23 #define __IP__                  , ip
24 #define __RET_IP__              , (unsigned long)__builtin_return_address(0)
25
26 /*
27  * This must be called with lock->wait_lock held.
28  */
29 extern void debug_mutex_set_owner(struct mutex *lock,
30                                   struct thread_info *new_owner __IP_DECL__);
31
32 static inline void debug_mutex_clear_owner(struct mutex *lock)
33 {
34         lock->owner = NULL;
35 }
36
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);
48
49 #define debug_spin_lock_save(lock, flags)               \
50         do {                                            \
51                 local_irq_save(flags);                  \
52                 if (debug_mutex_on)                     \
53                         spin_lock(lock);                \
54         } while (0)
55
56 #define debug_spin_unlock_restore(lock, flags)          \
57         do {                                            \
58                 if (debug_mutex_on)                     \
59                         spin_unlock(lock);              \
60                 local_irq_restore(flags);               \
61                 preempt_check_resched();                \
62         } while (0)
63
64 #define spin_lock_mutex(lock, flags)                    \
65         do {                                            \
66                 struct mutex *l = container_of(lock, struct mutex, wait_lock); \
67                                                         \
68                 DEBUG_WARN_ON(in_interrupt());          \
69                 debug_spin_lock_save(&debug_mutex_lock, flags); \
70                 spin_lock(lock);                        \
71                 DEBUG_WARN_ON(l->magic != l);           \
72         } while (0)
73
74 #define spin_unlock_mutex(lock, flags)                  \
75         do {                                            \
76                 spin_unlock(lock);                      \
77                 debug_spin_unlock_restore(&debug_mutex_lock, flags);    \
78         } while (0)
79
80 #define DEBUG_OFF()                                     \
81 do {                                                    \
82         if (debug_mutex_on) {                           \
83                 debug_mutex_on = 0;                     \
84                 console_verbose();                      \
85                 if (spin_is_locked(&debug_mutex_lock))  \
86                         spin_unlock(&debug_mutex_lock); \
87         }                                               \
88 } while (0)
89
90 #define DEBUG_BUG()                                     \
91 do {                                                    \
92         if (debug_mutex_on) {                           \
93                 DEBUG_OFF();                            \
94                 BUG();                                  \
95         }                                               \
96 } while (0)
97
98 #define DEBUG_WARN_ON(c)                                \
99 do {                                                    \
100         if (unlikely(c && debug_mutex_on)) {            \
101                 DEBUG_OFF();                            \
102                 WARN_ON(1);                             \
103         }                                               \
104 } while (0)
105
106 # define DEBUG_BUG_ON(c)                                \
107 do {                                                    \
108         if (unlikely(c))                                \
109                 DEBUG_BUG();                            \
110 } while (0)
111
112 #ifdef CONFIG_SMP
113 # define SMP_DEBUG_WARN_ON(c)                   DEBUG_WARN_ON(c)
114 # define SMP_DEBUG_BUG_ON(c)                    DEBUG_BUG_ON(c)
115 #else
116 # define SMP_DEBUG_WARN_ON(c)                   do { } while (0)
117 # define SMP_DEBUG_BUG_ON(c)                    do { } while (0)
118 #endif
119