diff options
author | Steven Rostedt <srostedt@redhat.com> | 2011-04-20 21:41:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-04-22 05:06:57 -0400 |
commit | f4185812aa046ecb97e8817e10148cacdd7a6baa (patch) | |
tree | a17a417d13586554f452df9fd251165c4d714a97 /kernel/lockdep.c | |
parent | 3003eba313dd0e0502dd71548c36fe7c19801ce5 (diff) |
lockdep: Print a nicer description for normal deadlocks
The lockdep output can be pretty cryptic, having nicer output
can save a lot of head scratching. When a normal deadlock
scenario is detected by lockdep (lock A -> lock B and there
exists a place where lock B -> lock A) we now get the following
new output:
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(lockB);
lock(lockA);
lock(lockB);
lock(lockA);
*** DEADLOCK ***
On cases where there's a deeper chair, it shows the partial
chain that can cause the issue:
Chain exists of:
lockC --> lockA --> lockB
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(lockB);
lock(lockA);
lock(lockB);
lock(lockC);
*** DEADLOCK ***
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/20110421014259.380621789@goodmis.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 7b2ffeedcebd..73cebd7aa719 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -1065,6 +1065,56 @@ print_circular_bug_entry(struct lock_list *target, int depth) | |||
1065 | return 0; | 1065 | return 0; |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | static void | ||
1069 | print_circular_lock_scenario(struct held_lock *src, | ||
1070 | struct held_lock *tgt, | ||
1071 | struct lock_list *prt) | ||
1072 | { | ||
1073 | struct lock_class *source = hlock_class(src); | ||
1074 | struct lock_class *target = hlock_class(tgt); | ||
1075 | struct lock_class *parent = prt->class; | ||
1076 | |||
1077 | /* | ||
1078 | * A direct locking problem where unsafe_class lock is taken | ||
1079 | * directly by safe_class lock, then all we need to show | ||
1080 | * is the deadlock scenario, as it is obvious that the | ||
1081 | * unsafe lock is taken under the safe lock. | ||
1082 | * | ||
1083 | * But if there is a chain instead, where the safe lock takes | ||
1084 | * an intermediate lock (middle_class) where this lock is | ||
1085 | * not the same as the safe lock, then the lock chain is | ||
1086 | * used to describe the problem. Otherwise we would need | ||
1087 | * to show a different CPU case for each link in the chain | ||
1088 | * from the safe_class lock to the unsafe_class lock. | ||
1089 | */ | ||
1090 | if (parent != source) { | ||
1091 | printk("Chain exists of:\n "); | ||
1092 | __print_lock_name(source); | ||
1093 | printk(" --> "); | ||
1094 | __print_lock_name(parent); | ||
1095 | printk(" --> "); | ||
1096 | __print_lock_name(target); | ||
1097 | printk("\n\n"); | ||
1098 | } | ||
1099 | |||
1100 | printk(" Possible unsafe locking scenario:\n\n"); | ||
1101 | printk(" CPU0 CPU1\n"); | ||
1102 | printk(" ---- ----\n"); | ||
1103 | printk(" lock("); | ||
1104 | __print_lock_name(target); | ||
1105 | printk(");\n"); | ||
1106 | printk(" lock("); | ||
1107 | __print_lock_name(parent); | ||
1108 | printk(");\n"); | ||
1109 | printk(" lock("); | ||
1110 | __print_lock_name(target); | ||
1111 | printk(");\n"); | ||
1112 | printk(" lock("); | ||
1113 | __print_lock_name(source); | ||
1114 | printk(");\n"); | ||
1115 | printk("\n *** DEADLOCK ***\n\n"); | ||
1116 | } | ||
1117 | |||
1068 | /* | 1118 | /* |
1069 | * When a circular dependency is detected, print the | 1119 | * When a circular dependency is detected, print the |
1070 | * header first: | 1120 | * header first: |
@@ -1108,6 +1158,7 @@ static noinline int print_circular_bug(struct lock_list *this, | |||
1108 | { | 1158 | { |
1109 | struct task_struct *curr = current; | 1159 | struct task_struct *curr = current; |
1110 | struct lock_list *parent; | 1160 | struct lock_list *parent; |
1161 | struct lock_list *first_parent; | ||
1111 | int depth; | 1162 | int depth; |
1112 | 1163 | ||
1113 | if (!debug_locks_off_graph_unlock() || debug_locks_silent) | 1164 | if (!debug_locks_off_graph_unlock() || debug_locks_silent) |
@@ -1121,6 +1172,7 @@ static noinline int print_circular_bug(struct lock_list *this, | |||
1121 | print_circular_bug_header(target, depth, check_src, check_tgt); | 1172 | print_circular_bug_header(target, depth, check_src, check_tgt); |
1122 | 1173 | ||
1123 | parent = get_lock_parent(target); | 1174 | parent = get_lock_parent(target); |
1175 | first_parent = parent; | ||
1124 | 1176 | ||
1125 | while (parent) { | 1177 | while (parent) { |
1126 | print_circular_bug_entry(parent, --depth); | 1178 | print_circular_bug_entry(parent, --depth); |
@@ -1128,6 +1180,9 @@ static noinline int print_circular_bug(struct lock_list *this, | |||
1128 | } | 1180 | } |
1129 | 1181 | ||
1130 | printk("\nother info that might help us debug this:\n\n"); | 1182 | printk("\nother info that might help us debug this:\n\n"); |
1183 | print_circular_lock_scenario(check_src, check_tgt, | ||
1184 | first_parent); | ||
1185 | |||
1131 | lockdep_print_held_locks(curr); | 1186 | lockdep_print_held_locks(curr); |
1132 | 1187 | ||
1133 | printk("\nstack backtrace:\n"); | 1188 | printk("\nstack backtrace:\n"); |