aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rtmutex-debug.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /kernel/rtmutex-debug.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'kernel/rtmutex-debug.c')
-rw-r--r--kernel/rtmutex-debug.c80
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() \
36do { \
37 if (rt_trace_on) { \
38 rt_trace_on = 0; \
39 console_verbose(); \
40 if (raw_spin_is_locked(&current->pi_lock)) \
41 raw_spin_unlock(&current->pi_lock); \
42 } \
43} while (0)
44
45# define TRACE_OFF_NOLOCK() \
46do { \
47 if (rt_trace_on) { \
48 rt_trace_on = 0; \
49 console_verbose(); \
50 } \
51} while (0)
52
53# define TRACE_BUG_LOCKED() \
54do { \
55 TRACE_OFF(); \
56 BUG(); \
57} while (0)
58
59# define TRACE_WARN_ON_LOCKED(c) \
60do { \
61 if (unlikely(c)) { \
62 TRACE_OFF(); \
63 WARN_ON(1); \
64 } \
65} while (0)
66
67# define TRACE_BUG_ON_LOCKED(c) \
68do { \
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 */
85static int rt_trace_on = 1;
86
32static void printk_task(struct task_struct *p) 87static 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
57void rt_mutex_debug_task_free(struct task_struct *task) 112void 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
134void debug_rt_mutex_lock(struct rt_mutex *lock) 186void debug_rt_mutex_lock(struct rt_mutex *lock)
@@ -137,7 +189,7 @@ void debug_rt_mutex_lock(struct rt_mutex *lock)
137 189
138void debug_rt_mutex_unlock(struct rt_mutex *lock) 190void 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
143void 195void
@@ -147,7 +199,7 @@ debug_rt_mutex_proxy_lock(struct rt_mutex *lock, struct task_struct *powner)
147 199
148void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock) 200void 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
153void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) 205void 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)
161void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter) 213void 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