diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/lockdep.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 5dcca26a8263..ce6d09e65ad1 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
| @@ -900,17 +900,18 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this, | |||
| 900 | unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)]; | 900 | unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)]; |
| 901 | static struct circular_queue lock_cq; | 901 | static struct circular_queue lock_cq; |
| 902 | 902 | ||
| 903 | static int __search_shortest_path(struct lock_list *source_entry, | 903 | static int __bfs(struct lock_list *source_entry, |
| 904 | struct lock_class *target, | 904 | void *data, |
| 905 | struct lock_list **target_entry, | 905 | int (*match)(struct lock_list *entry, void *data), |
| 906 | int forward) | 906 | struct lock_list **target_entry, |
| 907 | int forward) | ||
| 907 | { | 908 | { |
| 908 | struct lock_list *entry; | 909 | struct lock_list *entry; |
| 909 | struct list_head *head; | 910 | struct list_head *head; |
| 910 | struct circular_queue *cq = &lock_cq; | 911 | struct circular_queue *cq = &lock_cq; |
| 911 | int ret = 1; | 912 | int ret = 1; |
| 912 | 913 | ||
| 913 | if (source_entry->class == target) { | 914 | if (match(source_entry, data)) { |
| 914 | *target_entry = source_entry; | 915 | *target_entry = source_entry; |
| 915 | ret = 0; | 916 | ret = 0; |
| 916 | goto exit; | 917 | goto exit; |
| @@ -945,7 +946,7 @@ static int __search_shortest_path(struct lock_list *source_entry, | |||
| 945 | list_for_each_entry(entry, head, entry) { | 946 | list_for_each_entry(entry, head, entry) { |
| 946 | if (!lock_accessed(entry)) { | 947 | if (!lock_accessed(entry)) { |
| 947 | mark_lock_accessed(entry, lock); | 948 | mark_lock_accessed(entry, lock); |
| 948 | if (entry->class == target) { | 949 | if (match(entry, data)) { |
| 949 | *target_entry = entry; | 950 | *target_entry = entry; |
| 950 | ret = 0; | 951 | ret = 0; |
| 951 | goto exit; | 952 | goto exit; |
| @@ -962,19 +963,21 @@ exit: | |||
| 962 | return ret; | 963 | return ret; |
| 963 | } | 964 | } |
| 964 | 965 | ||
| 965 | static inline int __search_forward_shortest_path(struct lock_list *src_entry, | 966 | static inline int __bfs_forward(struct lock_list *src_entry, |
| 966 | struct lock_class *target, | 967 | void *data, |
| 967 | struct lock_list **target_entry) | 968 | int (*match)(struct lock_list *entry, void *data), |
| 969 | struct lock_list **target_entry) | ||
| 968 | { | 970 | { |
| 969 | return __search_shortest_path(src_entry, target, target_entry, 1); | 971 | return __bfs(src_entry, data, match, target_entry, 1); |
| 970 | 972 | ||
| 971 | } | 973 | } |
| 972 | 974 | ||
| 973 | static inline int __search_backward_shortest_path(struct lock_list *src_entry, | 975 | static inline int __bfs_backward(struct lock_list *src_entry, |
| 974 | struct lock_class *target, | 976 | void *data, |
| 975 | struct lock_list **target_entry) | 977 | int (*match)(struct lock_list *entry, void *data), |
| 978 | struct lock_list **target_entry) | ||
| 976 | { | 979 | { |
| 977 | return __search_shortest_path(src_entry, target, target_entry, 0); | 980 | return __bfs(src_entry, data, match, target_entry, 0); |
| 978 | 981 | ||
| 979 | } | 982 | } |
| 980 | 983 | ||
| @@ -1035,6 +1038,11 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth) | |||
| 1035 | return 0; | 1038 | return 0; |
| 1036 | } | 1039 | } |
| 1037 | 1040 | ||
| 1041 | static inline int class_equal(struct lock_list *entry, void *data) | ||
| 1042 | { | ||
| 1043 | return entry->class == data; | ||
| 1044 | } | ||
| 1045 | |||
| 1038 | static noinline int print_circular_bug(void) | 1046 | static noinline int print_circular_bug(void) |
| 1039 | { | 1047 | { |
| 1040 | struct task_struct *curr = current; | 1048 | struct task_struct *curr = current; |
| @@ -1052,9 +1060,10 @@ static noinline int print_circular_bug(void) | |||
| 1052 | if (!save_trace(&this.trace)) | 1060 | if (!save_trace(&this.trace)) |
| 1053 | return 0; | 1061 | return 0; |
| 1054 | 1062 | ||
| 1055 | result = __search_forward_shortest_path(&this, | 1063 | result = __bfs_forward(&this, |
| 1056 | hlock_class(check_target), | 1064 | hlock_class(check_target), |
| 1057 | &target); | 1065 | class_equal, |
| 1066 | &target); | ||
| 1058 | if (result) { | 1067 | if (result) { |
| 1059 | printk("\n%s:search shortest path failed:%d\n", __func__, | 1068 | printk("\n%s:search shortest path failed:%d\n", __func__, |
| 1060 | result); | 1069 | result); |
