blob: 8417b52ebd6539fb5bbfbf64eabd51228b2b24e5 [file] [log] [blame]
Ingo Molnar408894e2006-01-09 15:59:20 -08001/*
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
13extern spinlock_t debug_mutex_lock;
14extern struct list_head debug_mutex_held_locks;
15extern 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 */
29extern void debug_mutex_set_owner(struct mutex *lock,
30 struct thread_info *new_owner __IP_DECL__);
31
32static inline void debug_mutex_clear_owner(struct mutex *lock)
33{
34 lock->owner = NULL;
35}
36
37extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);
38extern void debug_mutex_wake_waiter(struct mutex *lock,
39 struct mutex_waiter *waiter);
40extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
41extern void debug_mutex_add_waiter(struct mutex *lock,
42 struct mutex_waiter *waiter,
43 struct thread_info *ti __IP_DECL__);
44extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
45 struct thread_info *ti);
46extern void debug_mutex_unlock(struct mutex *lock);
47extern void debug_mutex_init(struct mutex *lock, const char *name);
48
Ingo Molnar408894e2006-01-09 15:59:20 -080049#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
Ingo Molnar1fb00c62006-06-26 00:24:31 -070056#define debug_spin_unlock_restore(lock, flags) \
Ingo Molnar408894e2006-01-09 15:59:20 -080057 do { \
58 if (debug_mutex_on) \
59 spin_unlock(lock); \
60 local_irq_restore(flags); \
61 preempt_check_resched(); \
62 } while (0)
63
Ingo Molnar1fb00c62006-06-26 00:24:31 -070064#define spin_lock_mutex(lock, flags) \
Ingo Molnar408894e2006-01-09 15:59:20 -080065 do { \
66 struct mutex *l = container_of(lock, struct mutex, wait_lock); \
67 \
Ingo Molnar9e7f4d42006-07-03 00:24:30 -070068 DEBUG_LOCKS_WARN_ON(in_interrupt()); \
Ingo Molnar1fb00c62006-06-26 00:24:31 -070069 debug_spin_lock_save(&debug_mutex_lock, flags); \
Ingo Molnar408894e2006-01-09 15:59:20 -080070 spin_lock(lock); \
Ingo Molnar9e7f4d42006-07-03 00:24:30 -070071 DEBUG_LOCKS_WARN_ON(l->magic != l); \
Ingo Molnar408894e2006-01-09 15:59:20 -080072 } while (0)
73
Ingo Molnar1fb00c62006-06-26 00:24:31 -070074#define spin_unlock_mutex(lock, flags) \
Ingo Molnar408894e2006-01-09 15:59:20 -080075 do { \
76 spin_unlock(lock); \
Ingo Molnar1fb00c62006-06-26 00:24:31 -070077 debug_spin_unlock_restore(&debug_mutex_lock, flags); \
Ingo Molnar408894e2006-01-09 15:59:20 -080078 } while (0)
79
80#define DEBUG_OFF() \
81do { \
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() \
91do { \
92 if (debug_mutex_on) { \
93 DEBUG_OFF(); \
94 BUG(); \
95 } \
96} while (0)
97
Ingo Molnar9e7f4d42006-07-03 00:24:30 -070098#define DEBUG_LOCKS_WARN_ON(c) \
Ingo Molnar408894e2006-01-09 15:59:20 -080099do { \
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) \
107do { \
108 if (unlikely(c)) \
109 DEBUG_BUG(); \
110} while (0)
111
112#ifdef CONFIG_SMP
Ingo Molnar9e7f4d42006-07-03 00:24:30 -0700113# define SMP_DEBUG_LOCKS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c)
114# define SMP_DEBUG_BUG_ON(c) DEBUG_BUG_ON(c)
Ingo Molnar408894e2006-01-09 15:59:20 -0800115#else
Ingo Molnar9e7f4d42006-07-03 00:24:30 -0700116# define SMP_DEBUG_LOCKS_WARN_ON(c) do { } while (0)
117# define SMP_DEBUG_BUG_ON(c) do { } while (0)
Ingo Molnar408894e2006-01-09 15:59:20 -0800118#endif
119