diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index e33f6207f5b3..f76a24f2ac20 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -237,8 +237,10 @@ e locks. */ | |||
237 | trace->max_entries = trace->nr_entries; | 237 | trace->max_entries = trace->nr_entries; |
238 | 238 | ||
239 | nr_stack_trace_entries += trace->nr_entries; | 239 | nr_stack_trace_entries += trace->nr_entries; |
240 | if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) | 240 | if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) { |
241 | __raw_spin_unlock(&hash_lock); | ||
241 | return 0; | 242 | return 0; |
243 | } | ||
242 | 244 | ||
243 | if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) { | 245 | if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) { |
244 | __raw_spin_unlock(&hash_lock); | 246 | __raw_spin_unlock(&hash_lock); |
@@ -474,7 +476,8 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this, | |||
474 | return 0; | 476 | return 0; |
475 | 477 | ||
476 | entry->class = this; | 478 | entry->class = this; |
477 | save_trace(&entry->trace); | 479 | if (!save_trace(&entry->trace)) |
480 | return 0; | ||
478 | 481 | ||
479 | /* | 482 | /* |
480 | * Since we never remove from the dependency list, the list can | 483 | * Since we never remove from the dependency list, the list can |
@@ -562,8 +565,12 @@ static noinline int print_circular_bug_tail(void) | |||
562 | if (debug_locks_silent) | 565 | if (debug_locks_silent) |
563 | return 0; | 566 | return 0; |
564 | 567 | ||
568 | /* hash_lock unlocked by the header */ | ||
569 | __raw_spin_lock(&hash_lock); | ||
565 | this.class = check_source->class; | 570 | this.class = check_source->class; |
566 | save_trace(&this.trace); | 571 | if (!save_trace(&this.trace)) |
572 | return 0; | ||
573 | __raw_spin_unlock(&hash_lock); | ||
567 | print_circular_bug_entry(&this, 0); | 574 | print_circular_bug_entry(&this, 0); |
568 | 575 | ||
569 | printk("\nother info that might help us debug this:\n\n"); | 576 | printk("\nother info that might help us debug this:\n\n"); |
@@ -966,14 +973,11 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, | |||
966 | &prev->class->locks_after, next->acquire_ip); | 973 | &prev->class->locks_after, next->acquire_ip); |
967 | if (!ret) | 974 | if (!ret) |
968 | return 0; | 975 | return 0; |
969 | /* | 976 | |
970 | * Return value of 2 signals 'dependency already added', | ||
971 | * in that case we dont have to add the backlink either. | ||
972 | */ | ||
973 | if (ret == 2) | ||
974 | return 2; | ||
975 | ret = add_lock_to_list(next->class, prev->class, | 977 | ret = add_lock_to_list(next->class, prev->class, |
976 | &next->class->locks_before, next->acquire_ip); | 978 | &next->class->locks_before, next->acquire_ip); |
979 | if (!ret) | ||
980 | return 0; | ||
977 | 981 | ||
978 | /* | 982 | /* |
979 | * Debugging printouts: | 983 | * Debugging printouts: |
@@ -1025,7 +1029,8 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) | |||
1025 | * added: | 1029 | * added: |
1026 | */ | 1030 | */ |
1027 | if (hlock->read != 2) { | 1031 | if (hlock->read != 2) { |
1028 | check_prev_add(curr, hlock, next); | 1032 | if (!check_prev_add(curr, hlock, next)) |
1033 | return 0; | ||
1029 | /* | 1034 | /* |
1030 | * Stop after the first non-trylock entry, | 1035 | * Stop after the first non-trylock entry, |
1031 | * as non-trylock entries have added their | 1036 | * as non-trylock entries have added their |