diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /kernel/rtmutex-debug.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'kernel/rtmutex-debug.c')
-rw-r--r-- | kernel/rtmutex-debug.c | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c index 16502d3a71c..3c7cbc2c33b 100644 --- a/kernel/rtmutex-debug.c +++ b/kernel/rtmutex-debug.c | |||
@@ -18,7 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/export.h> | 21 | #include <linux/module.h> |
22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
23 | #include <linux/kallsyms.h> | 23 | #include <linux/kallsyms.h> |
24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
@@ -29,6 +29,61 @@ | |||
29 | 29 | ||
30 | #include "rtmutex_common.h" | 30 | #include "rtmutex_common.h" |
31 | 31 | ||
32 | # define TRACE_WARN_ON(x) WARN_ON(x) | ||
33 | # define TRACE_BUG_ON(x) BUG_ON(x) | ||
34 | |||
35 | # define TRACE_OFF() \ | ||
36 | do { \ | ||
37 | if (rt_trace_on) { \ | ||
38 | rt_trace_on = 0; \ | ||
39 | console_verbose(); \ | ||
40 | if (raw_spin_is_locked(¤t->pi_lock)) \ | ||
41 | raw_spin_unlock(¤t->pi_lock); \ | ||
42 | } \ | ||
43 | } while (0) | ||
44 | |||
45 | # define TRACE_OFF_NOLOCK() \ | ||
46 | do { \ | ||
47 | if (rt_trace_on) { \ | ||
48 | rt_trace_on = 0; \ | ||
49 | console_verbose(); \ | ||
50 | } \ | ||
51 | } while (0) | ||
52 | |||
53 | # define TRACE_BUG_LOCKED() \ | ||
54 | do { \ | ||
55 | TRACE_OFF(); \ | ||
56 | BUG(); \ | ||
57 | } while (0) | ||
58 | |||
59 | # define TRACE_WARN_ON_LOCKED(c) \ | ||
60 | do { \ | ||
61 | if (unlikely(c)) { \ | ||
62 | TRACE_OFF(); \ | ||
63 | WARN_ON(1); \ | ||
64 | } \ | ||
65 | } while (0) | ||
66 | |||
67 | # define TRACE_BUG_ON_LOCKED(c) \ | ||
68 | do { \ | ||
69 | if (unlikely(c)) \ | ||
70 | TRACE_BUG_LOCKED(); \ | ||
71 | } while (0) | ||
72 | |||
73 | #ifdef CONFIG_SMP | ||
74 | # define SMP_TRACE_BUG_ON_LOCKED(c) TRACE_BUG_ON_LOCKED(c) | ||
75 | #else | ||
76 | # define SMP_TRACE_BUG_ON_LOCKED(c) do { } while (0) | ||
77 | #endif | ||
78 | |||
79 | /* | ||
80 | * deadlock detection flag. We turn it off when we detect | ||
81 | * the first problem because we dont want to recurse back | ||
82 | * into the tracing code when doing error printk or | ||
83 | * executing a BUG(): | ||
84 | */ | ||
85 | static int rt_trace_on = 1; | ||
86 | |||
32 | static void printk_task(struct task_struct *p) | 87 | static void printk_task(struct task_struct *p) |
33 | { | 88 | { |
34 | if (p) | 89 | if (p) |
@@ -56,8 +111,8 @@ static void printk_lock(struct rt_mutex *lock, int print_owner) | |||
56 | 111 | ||
57 | void rt_mutex_debug_task_free(struct task_struct *task) | 112 | void rt_mutex_debug_task_free(struct task_struct *task) |
58 | { | 113 | { |
59 | DEBUG_LOCKS_WARN_ON(!plist_head_empty(&task->pi_waiters)); | 114 | WARN_ON(!plist_head_empty(&task->pi_waiters)); |
60 | DEBUG_LOCKS_WARN_ON(task->pi_blocked_on); | 115 | WARN_ON(task->pi_blocked_on); |
61 | } | 116 | } |
62 | 117 | ||
63 | /* | 118 | /* |
@@ -70,7 +125,7 @@ void debug_rt_mutex_deadlock(int detect, struct rt_mutex_waiter *act_waiter, | |||
70 | { | 125 | { |
71 | struct task_struct *task; | 126 | struct task_struct *task; |
72 | 127 | ||
73 | if (!debug_locks || detect || !act_waiter) | 128 | if (!rt_trace_on || detect || !act_waiter) |
74 | return; | 129 | return; |
75 | 130 | ||
76 | task = rt_mutex_owner(act_waiter->lock); | 131 | task = rt_mutex_owner(act_waiter->lock); |
@@ -84,7 +139,7 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter) | |||
84 | { | 139 | { |
85 | struct task_struct *task; | 140 | struct task_struct *task; |
86 | 141 | ||
87 | if (!waiter->deadlock_lock || !debug_locks) | 142 | if (!waiter->deadlock_lock || !rt_trace_on) |
88 | return; | 143 | return; |
89 | 144 | ||
90 | rcu_read_lock(); | 145 | rcu_read_lock(); |
@@ -94,14 +149,10 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter) | |||
94 | return; | 149 | return; |
95 | } | 150 | } |
96 | 151 | ||
97 | if (!debug_locks_off()) { | 152 | TRACE_OFF_NOLOCK(); |
98 | rcu_read_unlock(); | ||
99 | return; | ||
100 | } | ||
101 | 153 | ||
102 | printk("\n============================================\n"); | 154 | printk("\n============================================\n"); |
103 | printk( "[ BUG: circular locking deadlock detected! ]\n"); | 155 | printk( "[ BUG: circular locking deadlock detected! ]\n"); |
104 | printk("%s\n", print_tainted()); | ||
105 | printk( "--------------------------------------------\n"); | 156 | printk( "--------------------------------------------\n"); |
106 | printk("%s/%d is deadlocking current task %s/%d\n\n", | 157 | printk("%s/%d is deadlocking current task %s/%d\n\n", |
107 | task->comm, task_pid_nr(task), | 158 | task->comm, task_pid_nr(task), |
@@ -129,6 +180,7 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter) | |||
129 | 180 | ||
130 | printk("[ turning off deadlock detection." | 181 | printk("[ turning off deadlock detection." |
131 | "Please report this trace. ]\n\n"); | 182 | "Please report this trace. ]\n\n"); |
183 | local_irq_disable(); | ||
132 | } | 184 | } |
133 | 185 | ||
134 | void debug_rt_mutex_lock(struct rt_mutex *lock) | 186 | void debug_rt_mutex_lock(struct rt_mutex *lock) |
@@ -137,7 +189,7 @@ void debug_rt_mutex_lock(struct rt_mutex *lock) | |||
137 | 189 | ||
138 | void debug_rt_mutex_unlock(struct rt_mutex *lock) | 190 | void debug_rt_mutex_unlock(struct rt_mutex *lock) |
139 | { | 191 | { |
140 | DEBUG_LOCKS_WARN_ON(rt_mutex_owner(lock) != current); | 192 | TRACE_WARN_ON_LOCKED(rt_mutex_owner(lock) != current); |
141 | } | 193 | } |
142 | 194 | ||
143 | void | 195 | void |
@@ -147,7 +199,7 @@ debug_rt_mutex_proxy_lock(struct rt_mutex *lock, struct task_struct *powner) | |||
147 | 199 | ||
148 | void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock) | 200 | void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock) |
149 | { | 201 | { |
150 | DEBUG_LOCKS_WARN_ON(!rt_mutex_owner(lock)); | 202 | TRACE_WARN_ON_LOCKED(!rt_mutex_owner(lock)); |
151 | } | 203 | } |
152 | 204 | ||
153 | void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) | 205 | void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) |
@@ -161,8 +213,8 @@ void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) | |||
161 | void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter) | 213 | void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter) |
162 | { | 214 | { |
163 | put_pid(waiter->deadlock_task_pid); | 215 | put_pid(waiter->deadlock_task_pid); |
164 | DEBUG_LOCKS_WARN_ON(!plist_node_empty(&waiter->list_entry)); | 216 | TRACE_WARN_ON(!plist_node_empty(&waiter->list_entry)); |
165 | DEBUG_LOCKS_WARN_ON(!plist_node_empty(&waiter->pi_list_entry)); | 217 | TRACE_WARN_ON(!plist_node_empty(&waiter->pi_list_entry)); |
166 | memset(waiter, 0x22, sizeof(*waiter)); | 218 | memset(waiter, 0x22, sizeof(*waiter)); |
167 | } | 219 | } |
168 | 220 | ||