aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 2d616f4d853c..592c576d77a7 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -490,7 +490,7 @@ static void print_lock_dependencies(struct lock_class *class, int depth)
490 * Add a new dependency to the head of the list: 490 * Add a new dependency to the head of the list:
491 */ 491 */
492static int add_lock_to_list(struct lock_class *class, struct lock_class *this, 492static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
493 struct list_head *head, unsigned long ip) 493 struct list_head *head, unsigned long ip, int distance)
494{ 494{
495 struct lock_list *entry; 495 struct lock_list *entry;
496 /* 496 /*
@@ -502,6 +502,7 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
502 return 0; 502 return 0;
503 503
504 entry->class = this; 504 entry->class = this;
505 entry->distance = distance;
505 if (!save_trace(&entry->trace)) 506 if (!save_trace(&entry->trace))
506 return 0; 507 return 0;
507 508
@@ -906,7 +907,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next,
906 */ 907 */
907static int 908static int
908check_prev_add(struct task_struct *curr, struct held_lock *prev, 909check_prev_add(struct task_struct *curr, struct held_lock *prev,
909 struct held_lock *next) 910 struct held_lock *next, int distance)
910{ 911{
911 struct lock_list *entry; 912 struct lock_list *entry;
912 int ret; 913 int ret;
@@ -984,8 +985,11 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
984 * L2 added to its dependency list, due to the first chain.) 985 * L2 added to its dependency list, due to the first chain.)
985 */ 986 */
986 list_for_each_entry(entry, &prev->class->locks_after, entry) { 987 list_for_each_entry(entry, &prev->class->locks_after, entry) {
987 if (entry->class == next->class) 988 if (entry->class == next->class) {
989 if (distance == 1)
990 entry->distance = 1;
988 return 2; 991 return 2;
992 }
989 } 993 }
990 994
991 /* 995 /*
@@ -993,12 +997,13 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
993 * to the previous lock's dependency list: 997 * to the previous lock's dependency list:
994 */ 998 */
995 ret = add_lock_to_list(prev->class, next->class, 999 ret = add_lock_to_list(prev->class, next->class,
996 &prev->class->locks_after, next->acquire_ip); 1000 &prev->class->locks_after, next->acquire_ip, distance);
1001
997 if (!ret) 1002 if (!ret)
998 return 0; 1003 return 0;
999 1004
1000 ret = add_lock_to_list(next->class, prev->class, 1005 ret = add_lock_to_list(next->class, prev->class,
1001 &next->class->locks_before, next->acquire_ip); 1006 &next->class->locks_before, next->acquire_ip, distance);
1002 if (!ret) 1007 if (!ret)
1003 return 0; 1008 return 0;
1004 1009
@@ -1046,13 +1051,14 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
1046 goto out_bug; 1051 goto out_bug;
1047 1052
1048 for (;;) { 1053 for (;;) {
1054 int distance = curr->lockdep_depth - depth + 1;
1049 hlock = curr->held_locks + depth-1; 1055 hlock = curr->held_locks + depth-1;
1050 /* 1056 /*
1051 * Only non-recursive-read entries get new dependencies 1057 * Only non-recursive-read entries get new dependencies
1052 * added: 1058 * added:
1053 */ 1059 */
1054 if (hlock->read != 2) { 1060 if (hlock->read != 2) {
1055 if (!check_prev_add(curr, hlock, next)) 1061 if (!check_prev_add(curr, hlock, next, distance))
1056 return 0; 1062 return 0;
1057 /* 1063 /*
1058 * Stop after the first non-trylock entry, 1064 * Stop after the first non-trylock entry,
@@ -2779,4 +2785,3 @@ void debug_show_held_locks(struct task_struct *task)
2779} 2785}
2780 2786
2781EXPORT_SYMBOL_GPL(debug_show_held_locks); 2787EXPORT_SYMBOL_GPL(debug_show_held_locks);
2782