diff options
author | Ming Lei <tom.leiming@gmail.com> | 2009-07-16 09:44:29 -0400 |
---|---|---|
committer | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-07-24 04:49:48 -0400 |
commit | 9e2d551ea0d767c0d624965f0c273e942f4be536 (patch) | |
tree | 0568e3002063bb174cbfc6f18ec0b5d562b0f77a | |
parent | d588e46155e9c51217b9840db1e94a0f594c1af2 (diff) |
lockdep: Introduce match function to BFS
1,introduce match() to BFS in order to make it usable to
match different pattern;
2,also rename some functions to make them more suitable.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1246201486-7308-4-git-send-email-tom.leiming@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-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); |