diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-26 17:25:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-26 17:25:52 -0500 |
commit | 1eefdec18eded41833401cfd64749643ff72e7da (patch) | |
tree | cf9d35939e239b7d1ed3194bec7f4d51409c2d50 | |
parent | 684019dd1f0092b4ffce4958c84aff0891deac83 (diff) | |
parent | 80eb865768703c0f85a0603762742ae1dedf21f0 (diff) |
Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Ingo Molnar:
"The main change in this cycle are initial preparatory bits of dynamic
lockdep keys support from Bart Van Assche.
There are also misc changes, a comment cleanup and a data structure
cleanup"
* 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched/fair: Clean up comment in nohz_idle_balance()
locking/lockdep: Stop using RCU primitives to access 'all_lock_classes'
locking/lockdep: Make concurrent lockdep_reset_lock() calls safe
locking/lockdep: Remove a superfluous INIT_LIST_HEAD() statement
locking/lockdep: Introduce lock_class_cache_is_registered()
locking/lockdep: Inline __lockdep_init_map()
locking/lockdep: Declare local symbols static
tools/lib/lockdep/tests: Test the lockdep_reset_lock() implementation
tools/lib/lockdep: Add dummy print_irqtrace_events() implementation
tools/lib/lockdep: Rename "trywlock" into "trywrlock"
tools/lib/lockdep/tests: Run lockdep tests a second time under Valgrind
tools/lib/lockdep/tests: Improve testing accuracy
tools/lib/lockdep/tests: Fix shellcheck warnings
tools/lib/lockdep/tests: Display compiler warning and error messages
locking/lockdep: Remove ::version from lock_class structure
26 files changed, 131 insertions, 53 deletions
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 1fd82ff99c65..c5335df2372f 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h | |||
@@ -97,8 +97,6 @@ struct lock_class { | |||
97 | * Generation counter, when doing certain classes of graph walking, | 97 | * Generation counter, when doing certain classes of graph walking, |
98 | * to ensure that we check one node only once: | 98 | * to ensure that we check one node only once: |
99 | */ | 99 | */ |
100 | unsigned int version; | ||
101 | |||
102 | int name_version; | 100 | int name_version; |
103 | const char *name; | 101 | const char *name; |
104 | 102 | ||
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index ef27f98714c0..95932333a48b 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
@@ -138,6 +138,9 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; | |||
138 | * get freed - this significantly simplifies the debugging code. | 138 | * get freed - this significantly simplifies the debugging code. |
139 | */ | 139 | */ |
140 | unsigned long nr_lock_classes; | 140 | unsigned long nr_lock_classes; |
141 | #ifndef CONFIG_DEBUG_LOCKDEP | ||
142 | static | ||
143 | #endif | ||
141 | struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; | 144 | struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; |
142 | 145 | ||
143 | static inline struct lock_class *hlock_class(struct held_lock *hlock) | 146 | static inline struct lock_class *hlock_class(struct held_lock *hlock) |
@@ -626,7 +629,8 @@ static int static_obj(void *obj) | |||
626 | 629 | ||
627 | /* | 630 | /* |
628 | * To make lock name printouts unique, we calculate a unique | 631 | * To make lock name printouts unique, we calculate a unique |
629 | * class->name_version generation counter: | 632 | * class->name_version generation counter. The caller must hold the graph |
633 | * lock. | ||
630 | */ | 634 | */ |
631 | static int count_matching_names(struct lock_class *new_class) | 635 | static int count_matching_names(struct lock_class *new_class) |
632 | { | 636 | { |
@@ -636,7 +640,7 @@ static int count_matching_names(struct lock_class *new_class) | |||
636 | if (!new_class->name) | 640 | if (!new_class->name) |
637 | return 0; | 641 | return 0; |
638 | 642 | ||
639 | list_for_each_entry_rcu(class, &all_lock_classes, lock_entry) { | 643 | list_for_each_entry(class, &all_lock_classes, lock_entry) { |
640 | if (new_class->key - new_class->subclass == class->key) | 644 | if (new_class->key - new_class->subclass == class->key) |
641 | return class->name_version; | 645 | return class->name_version; |
642 | if (class->name && !strcmp(class->name, new_class->name)) | 646 | if (class->name && !strcmp(class->name, new_class->name)) |
@@ -789,7 +793,6 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) | |||
789 | class->key = key; | 793 | class->key = key; |
790 | class->name = lock->name; | 794 | class->name = lock->name; |
791 | class->subclass = subclass; | 795 | class->subclass = subclass; |
792 | INIT_LIST_HEAD(&class->lock_entry); | ||
793 | INIT_LIST_HEAD(&class->locks_before); | 796 | INIT_LIST_HEAD(&class->locks_before); |
794 | INIT_LIST_HEAD(&class->locks_after); | 797 | INIT_LIST_HEAD(&class->locks_after); |
795 | class->name_version = count_matching_names(class); | 798 | class->name_version = count_matching_names(class); |
@@ -801,7 +804,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) | |||
801 | /* | 804 | /* |
802 | * Add it to the global list of classes: | 805 | * Add it to the global list of classes: |
803 | */ | 806 | */ |
804 | list_add_tail_rcu(&class->lock_entry, &all_lock_classes); | 807 | list_add_tail(&class->lock_entry, &all_lock_classes); |
805 | 808 | ||
806 | if (verbose(class)) { | 809 | if (verbose(class)) { |
807 | graph_unlock(); | 810 | graph_unlock(); |
@@ -3088,7 +3091,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | |||
3088 | /* | 3091 | /* |
3089 | * Initialize a lock instance's lock-class mapping info: | 3092 | * Initialize a lock instance's lock-class mapping info: |
3090 | */ | 3093 | */ |
3091 | static void __lockdep_init_map(struct lockdep_map *lock, const char *name, | 3094 | void lockdep_init_map(struct lockdep_map *lock, const char *name, |
3092 | struct lock_class_key *key, int subclass) | 3095 | struct lock_class_key *key, int subclass) |
3093 | { | 3096 | { |
3094 | int i; | 3097 | int i; |
@@ -3144,12 +3147,6 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, | |||
3144 | raw_local_irq_restore(flags); | 3147 | raw_local_irq_restore(flags); |
3145 | } | 3148 | } |
3146 | } | 3149 | } |
3147 | |||
3148 | void lockdep_init_map(struct lockdep_map *lock, const char *name, | ||
3149 | struct lock_class_key *key, int subclass) | ||
3150 | { | ||
3151 | __lockdep_init_map(lock, name, key, subclass); | ||
3152 | } | ||
3153 | EXPORT_SYMBOL_GPL(lockdep_init_map); | 3150 | EXPORT_SYMBOL_GPL(lockdep_init_map); |
3154 | 3151 | ||
3155 | struct lock_class_key __lockdep_no_validate__; | 3152 | struct lock_class_key __lockdep_no_validate__; |
@@ -4126,6 +4123,9 @@ void lockdep_reset(void) | |||
4126 | raw_local_irq_restore(flags); | 4123 | raw_local_irq_restore(flags); |
4127 | } | 4124 | } |
4128 | 4125 | ||
4126 | /* | ||
4127 | * Remove all references to a lock class. The caller must hold the graph lock. | ||
4128 | */ | ||
4129 | static void zap_class(struct lock_class *class) | 4129 | static void zap_class(struct lock_class *class) |
4130 | { | 4130 | { |
4131 | int i; | 4131 | int i; |
@@ -4142,7 +4142,7 @@ static void zap_class(struct lock_class *class) | |||
4142 | * Unhash the class and remove it from the all_lock_classes list: | 4142 | * Unhash the class and remove it from the all_lock_classes list: |
4143 | */ | 4143 | */ |
4144 | hlist_del_rcu(&class->hash_entry); | 4144 | hlist_del_rcu(&class->hash_entry); |
4145 | list_del_rcu(&class->lock_entry); | 4145 | list_del(&class->lock_entry); |
4146 | 4146 | ||
4147 | RCU_INIT_POINTER(class->key, NULL); | 4147 | RCU_INIT_POINTER(class->key, NULL); |
4148 | RCU_INIT_POINTER(class->name, NULL); | 4148 | RCU_INIT_POINTER(class->name, NULL); |
@@ -4204,15 +4204,36 @@ void lockdep_free_key_range(void *start, unsigned long size) | |||
4204 | */ | 4204 | */ |
4205 | } | 4205 | } |
4206 | 4206 | ||
4207 | void lockdep_reset_lock(struct lockdep_map *lock) | 4207 | /* |
4208 | * Check whether any element of the @lock->class_cache[] array refers to a | ||
4209 | * registered lock class. The caller must hold either the graph lock or the | ||
4210 | * RCU read lock. | ||
4211 | */ | ||
4212 | static bool lock_class_cache_is_registered(struct lockdep_map *lock) | ||
4208 | { | 4213 | { |
4209 | struct lock_class *class; | 4214 | struct lock_class *class; |
4210 | struct hlist_head *head; | 4215 | struct hlist_head *head; |
4211 | unsigned long flags; | ||
4212 | int i, j; | 4216 | int i, j; |
4213 | int locked; | 4217 | |
4218 | for (i = 0; i < CLASSHASH_SIZE; i++) { | ||
4219 | head = classhash_table + i; | ||
4220 | hlist_for_each_entry_rcu(class, head, hash_entry) { | ||
4221 | for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) | ||
4222 | if (lock->class_cache[j] == class) | ||
4223 | return true; | ||
4224 | } | ||
4225 | } | ||
4226 | return false; | ||
4227 | } | ||
4228 | |||
4229 | void lockdep_reset_lock(struct lockdep_map *lock) | ||
4230 | { | ||
4231 | struct lock_class *class; | ||
4232 | unsigned long flags; | ||
4233 | int j, locked; | ||
4214 | 4234 | ||
4215 | raw_local_irq_save(flags); | 4235 | raw_local_irq_save(flags); |
4236 | locked = graph_lock(); | ||
4216 | 4237 | ||
4217 | /* | 4238 | /* |
4218 | * Remove all classes this lock might have: | 4239 | * Remove all classes this lock might have: |
@@ -4229,25 +4250,14 @@ void lockdep_reset_lock(struct lockdep_map *lock) | |||
4229 | * Debug check: in the end all mapped classes should | 4250 | * Debug check: in the end all mapped classes should |
4230 | * be gone. | 4251 | * be gone. |
4231 | */ | 4252 | */ |
4232 | locked = graph_lock(); | 4253 | if (unlikely(lock_class_cache_is_registered(lock))) { |
4233 | for (i = 0; i < CLASSHASH_SIZE; i++) { | 4254 | if (debug_locks_off_graph_unlock()) { |
4234 | head = classhash_table + i; | 4255 | /* |
4235 | hlist_for_each_entry_rcu(class, head, hash_entry) { | 4256 | * We all just reset everything, how did it match? |
4236 | int match = 0; | 4257 | */ |
4237 | 4258 | WARN_ON(1); | |
4238 | for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) | ||
4239 | match |= class == lock->class_cache[j]; | ||
4240 | |||
4241 | if (unlikely(match)) { | ||
4242 | if (debug_locks_off_graph_unlock()) { | ||
4243 | /* | ||
4244 | * We all just reset everything, how did it match? | ||
4245 | */ | ||
4246 | WARN_ON(1); | ||
4247 | } | ||
4248 | goto out_restore; | ||
4249 | } | ||
4250 | } | 4259 | } |
4260 | goto out_restore; | ||
4251 | } | 4261 | } |
4252 | if (locked) | 4262 | if (locked) |
4253 | graph_unlock(); | 4263 | graph_unlock(); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ac855b2f4774..db514993565b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -9533,9 +9533,7 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) | |||
9533 | return false; | 9533 | return false; |
9534 | } | 9534 | } |
9535 | 9535 | ||
9536 | /* | 9536 | /* could be _relaxed() */ |
9537 | * barrier, pairs with nohz_balance_enter_idle(), ensures ... | ||
9538 | */ | ||
9539 | flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu)); | 9537 | flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu)); |
9540 | if (!(flags & NOHZ_KICK_MASK)) | 9538 | if (!(flags & NOHZ_KICK_MASK)) |
9541 | return false; | 9539 | return false; |
diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h index 8862da80995a..d640a9761f09 100644 --- a/tools/lib/lockdep/include/liblockdep/common.h +++ b/tools/lib/lockdep/include/liblockdep/common.h | |||
@@ -44,6 +44,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | |||
44 | struct lockdep_map *nest_lock, unsigned long ip); | 44 | struct lockdep_map *nest_lock, unsigned long ip); |
45 | void lock_release(struct lockdep_map *lock, int nested, | 45 | void lock_release(struct lockdep_map *lock, int nested, |
46 | unsigned long ip); | 46 | unsigned long ip); |
47 | void lockdep_reset_lock(struct lockdep_map *lock); | ||
47 | extern void debug_check_no_locks_freed(const void *from, unsigned long len); | 48 | extern void debug_check_no_locks_freed(const void *from, unsigned long len); |
48 | 49 | ||
49 | #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ | 50 | #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ |
diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h index a80ac39f966e..2073d4e1f2f0 100644 --- a/tools/lib/lockdep/include/liblockdep/mutex.h +++ b/tools/lib/lockdep/include/liblockdep/mutex.h | |||
@@ -54,6 +54,7 @@ static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *l | |||
54 | 54 | ||
55 | static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) | 55 | static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) |
56 | { | 56 | { |
57 | lockdep_reset_lock(&lock->dep_map); | ||
57 | return pthread_mutex_destroy(&lock->mutex); | 58 | return pthread_mutex_destroy(&lock->mutex); |
58 | } | 59 | } |
59 | 60 | ||
diff --git a/tools/lib/lockdep/include/liblockdep/rwlock.h b/tools/lib/lockdep/include/liblockdep/rwlock.h index a96c3bf0fef1..365762e3a1ea 100644 --- a/tools/lib/lockdep/include/liblockdep/rwlock.h +++ b/tools/lib/lockdep/include/liblockdep/rwlock.h | |||
@@ -60,10 +60,10 @@ static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_ | |||
60 | return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; | 60 | return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock) | 63 | static inline int liblockdep_pthread_rwlock_trywrlock(liblockdep_pthread_rwlock_t *lock) |
64 | { | 64 | { |
65 | lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); | 65 | lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); |
66 | return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0; | 66 | return pthread_rwlock_trywrlock(&lock->rwlock) == 0 ? 1 : 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) | 69 | static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) |
@@ -79,7 +79,7 @@ static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) | |||
79 | #define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock | 79 | #define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock |
80 | #define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock | 80 | #define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock |
81 | #define pthread_rwlock_tryrdlock liblockdep_pthread_rwlock_tryrdlock | 81 | #define pthread_rwlock_tryrdlock liblockdep_pthread_rwlock_tryrdlock |
82 | #define pthread_rwlock_trywlock liblockdep_pthread_rwlock_trywlock | 82 | #define pthread_rwlock_trywrlock liblockdep_pthread_rwlock_trywrlock |
83 | #define pthread_rwlock_destroy liblockdep_rwlock_destroy | 83 | #define pthread_rwlock_destroy liblockdep_rwlock_destroy |
84 | 84 | ||
85 | #endif | 85 | #endif |
diff --git a/tools/lib/lockdep/lockdep.c b/tools/lib/lockdep/lockdep.c index 6002fcf2f9bc..348a9d0fb766 100644 --- a/tools/lib/lockdep/lockdep.c +++ b/tools/lib/lockdep/lockdep.c | |||
@@ -15,6 +15,11 @@ u32 prandom_u32(void) | |||
15 | abort(); | 15 | abort(); |
16 | } | 16 | } |
17 | 17 | ||
18 | void print_irqtrace_events(struct task_struct *curr) | ||
19 | { | ||
20 | abort(); | ||
21 | } | ||
22 | |||
18 | static struct new_utsname *init_utsname(void) | 23 | static struct new_utsname *init_utsname(void) |
19 | { | 24 | { |
20 | static struct new_utsname n = (struct new_utsname) { | 25 | static struct new_utsname n = (struct new_utsname) { |
diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index 2e570a188f16..c8fbd0306960 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh | |||
@@ -1,32 +1,47 @@ | |||
1 | #! /bin/bash | 1 | #! /bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | make &> /dev/null | 4 | if ! make >/dev/null; then |
5 | echo "Building liblockdep failed." | ||
6 | echo "FAILED!" | ||
7 | exit 1 | ||
8 | fi | ||
5 | 9 | ||
6 | for i in `ls tests/*.c`; do | 10 | find tests -name '*.c' | sort | while read -r i; do |
7 | testname=$(basename "$i" .c) | 11 | testname=$(basename "$i" .c) |
8 | gcc -o tests/$testname -pthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null | ||
9 | echo -ne "$testname... " | 12 | echo -ne "$testname... " |
10 | if [ $(timeout 1 ./tests/$testname 2>&1 | wc -l) -gt 0 ]; then | 13 | if gcc -o "tests/$testname" -pthread "$i" liblockdep.a -Iinclude -D__USE_LIBLOCKDEP && |
14 | timeout 1 "tests/$testname" 2>&1 | "tests/${testname}.sh"; then | ||
11 | echo "PASSED!" | 15 | echo "PASSED!" |
12 | else | 16 | else |
13 | echo "FAILED!" | 17 | echo "FAILED!" |
14 | fi | 18 | fi |
15 | if [ -f "tests/$testname" ]; then | 19 | rm -f "tests/$testname" |
16 | rm tests/$testname | ||
17 | fi | ||
18 | done | 20 | done |
19 | 21 | ||
20 | for i in `ls tests/*.c`; do | 22 | find tests -name '*.c' | sort | while read -r i; do |
21 | testname=$(basename "$i" .c) | 23 | testname=$(basename "$i" .c) |
22 | gcc -o tests/$testname -pthread -Iinclude $i &> /dev/null | ||
23 | echo -ne "(PRELOAD) $testname... " | 24 | echo -ne "(PRELOAD) $testname... " |
24 | if [ $(timeout 1 ./lockdep ./tests/$testname 2>&1 | wc -l) -gt 0 ]; then | 25 | if gcc -o "tests/$testname" -pthread -Iinclude "$i" && |
26 | timeout 1 ./lockdep "tests/$testname" 2>&1 | | ||
27 | "tests/${testname}.sh"; then | ||
25 | echo "PASSED!" | 28 | echo "PASSED!" |
26 | else | 29 | else |
27 | echo "FAILED!" | 30 | echo "FAILED!" |
28 | fi | 31 | fi |
29 | if [ -f "tests/$testname" ]; then | 32 | rm -f "tests/$testname" |
30 | rm tests/$testname | 33 | done |
34 | |||
35 | find tests -name '*.c' | sort | while read -r i; do | ||
36 | testname=$(basename "$i" .c) | ||
37 | echo -ne "(PRELOAD + Valgrind) $testname... " | ||
38 | if gcc -o "tests/$testname" -pthread -Iinclude "$i" && | ||
39 | { timeout 10 valgrind --read-var-info=yes ./lockdep "./tests/$testname" >& "tests/${testname}.vg.out"; true; } && | ||
40 | "tests/${testname}.sh" < "tests/${testname}.vg.out" && | ||
41 | ! grep -Eq '(^==[0-9]*== (Invalid |Uninitialised ))|Mismatched free|Source and destination overlap| UME ' "tests/${testname}.vg.out"; then | ||
42 | echo "PASSED!" | ||
43 | else | ||
44 | echo "FAILED!" | ||
31 | fi | 45 | fi |
46 | rm -f "tests/$testname" | ||
32 | done | 47 | done |
diff --git a/tools/lib/lockdep/tests/AA.sh b/tools/lib/lockdep/tests/AA.sh new file mode 100644 index 000000000000..f39b32865074 --- /dev/null +++ b/tools/lib/lockdep/tests/AA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible recursive locking detected' | ||
diff --git a/tools/lib/lockdep/tests/ABA.sh b/tools/lib/lockdep/tests/ABA.sh new file mode 100644 index 000000000000..f39b32865074 --- /dev/null +++ b/tools/lib/lockdep/tests/ABA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible recursive locking detected' | ||
diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c index 1460afd33d71..623313f54720 100644 --- a/tools/lib/lockdep/tests/ABBA.c +++ b/tools/lib/lockdep/tests/ABBA.c | |||
@@ -11,4 +11,7 @@ void main(void) | |||
11 | 11 | ||
12 | LOCK_UNLOCK_2(a, b); | 12 | LOCK_UNLOCK_2(a, b); |
13 | LOCK_UNLOCK_2(b, a); | 13 | LOCK_UNLOCK_2(b, a); |
14 | |||
15 | pthread_mutex_destroy(&b); | ||
16 | pthread_mutex_destroy(&a); | ||
14 | } | 17 | } |
diff --git a/tools/lib/lockdep/tests/ABBA.sh b/tools/lib/lockdep/tests/ABBA.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABBA_2threads.sh b/tools/lib/lockdep/tests/ABBA_2threads.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBA_2threads.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c index a54c1b2af118..48446129d496 100644 --- a/tools/lib/lockdep/tests/ABBCCA.c +++ b/tools/lib/lockdep/tests/ABBCCA.c | |||
@@ -13,4 +13,8 @@ void main(void) | |||
13 | LOCK_UNLOCK_2(a, b); | 13 | LOCK_UNLOCK_2(a, b); |
14 | LOCK_UNLOCK_2(b, c); | 14 | LOCK_UNLOCK_2(b, c); |
15 | LOCK_UNLOCK_2(c, a); | 15 | LOCK_UNLOCK_2(c, a); |
16 | |||
17 | pthread_mutex_destroy(&c); | ||
18 | pthread_mutex_destroy(&b); | ||
19 | pthread_mutex_destroy(&a); | ||
16 | } | 20 | } |
diff --git a/tools/lib/lockdep/tests/ABBCCA.sh b/tools/lib/lockdep/tests/ABBCCA.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBCCA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c index aa5d194e8869..3570bf7b3804 100644 --- a/tools/lib/lockdep/tests/ABBCCDDA.c +++ b/tools/lib/lockdep/tests/ABBCCDDA.c | |||
@@ -15,4 +15,9 @@ void main(void) | |||
15 | LOCK_UNLOCK_2(b, c); | 15 | LOCK_UNLOCK_2(b, c); |
16 | LOCK_UNLOCK_2(c, d); | 16 | LOCK_UNLOCK_2(c, d); |
17 | LOCK_UNLOCK_2(d, a); | 17 | LOCK_UNLOCK_2(d, a); |
18 | |||
19 | pthread_mutex_destroy(&d); | ||
20 | pthread_mutex_destroy(&c); | ||
21 | pthread_mutex_destroy(&b); | ||
22 | pthread_mutex_destroy(&a); | ||
18 | } | 23 | } |
diff --git a/tools/lib/lockdep/tests/ABBCCDDA.sh b/tools/lib/lockdep/tests/ABBCCDDA.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBCCDDA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c index b54a08e60416..a1c4659894cd 100644 --- a/tools/lib/lockdep/tests/ABCABC.c +++ b/tools/lib/lockdep/tests/ABCABC.c | |||
@@ -13,4 +13,8 @@ void main(void) | |||
13 | LOCK_UNLOCK_2(a, b); | 13 | LOCK_UNLOCK_2(a, b); |
14 | LOCK_UNLOCK_2(c, a); | 14 | LOCK_UNLOCK_2(c, a); |
15 | LOCK_UNLOCK_2(b, c); | 15 | LOCK_UNLOCK_2(b, c); |
16 | |||
17 | pthread_mutex_destroy(&c); | ||
18 | pthread_mutex_destroy(&b); | ||
19 | pthread_mutex_destroy(&a); | ||
16 | } | 20 | } |
diff --git a/tools/lib/lockdep/tests/ABCABC.sh b/tools/lib/lockdep/tests/ABCABC.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABCABC.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c index a56742250d86..335af1c90ab5 100644 --- a/tools/lib/lockdep/tests/ABCDBCDA.c +++ b/tools/lib/lockdep/tests/ABCDBCDA.c | |||
@@ -15,4 +15,9 @@ void main(void) | |||
15 | LOCK_UNLOCK_2(c, d); | 15 | LOCK_UNLOCK_2(c, d); |
16 | LOCK_UNLOCK_2(b, c); | 16 | LOCK_UNLOCK_2(b, c); |
17 | LOCK_UNLOCK_2(d, a); | 17 | LOCK_UNLOCK_2(d, a); |
18 | |||
19 | pthread_mutex_destroy(&d); | ||
20 | pthread_mutex_destroy(&c); | ||
21 | pthread_mutex_destroy(&b); | ||
22 | pthread_mutex_destroy(&a); | ||
18 | } | 23 | } |
diff --git a/tools/lib/lockdep/tests/ABCDBCDA.sh b/tools/lib/lockdep/tests/ABCDBCDA.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABCDBCDA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c index 238a3353f3c3..3c5972863049 100644 --- a/tools/lib/lockdep/tests/ABCDBDDA.c +++ b/tools/lib/lockdep/tests/ABCDBDDA.c | |||
@@ -15,4 +15,9 @@ void main(void) | |||
15 | LOCK_UNLOCK_2(c, d); | 15 | LOCK_UNLOCK_2(c, d); |
16 | LOCK_UNLOCK_2(b, d); | 16 | LOCK_UNLOCK_2(b, d); |
17 | LOCK_UNLOCK_2(d, a); | 17 | LOCK_UNLOCK_2(d, a); |
18 | |||
19 | pthread_mutex_destroy(&d); | ||
20 | pthread_mutex_destroy(&c); | ||
21 | pthread_mutex_destroy(&b); | ||
22 | pthread_mutex_destroy(&a); | ||
18 | } | 23 | } |
diff --git a/tools/lib/lockdep/tests/ABCDBDDA.sh b/tools/lib/lockdep/tests/ABCDBDDA.sh new file mode 100644 index 000000000000..fc31c607a5a8 --- /dev/null +++ b/tools/lib/lockdep/tests/ABCDBDDA.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible circular locking dependency detected' | ||
diff --git a/tools/lib/lockdep/tests/WW.sh b/tools/lib/lockdep/tests/WW.sh new file mode 100644 index 000000000000..f39b32865074 --- /dev/null +++ b/tools/lib/lockdep/tests/WW.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: possible recursive locking detected' | ||
diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c index 34cf32f689de..dba25064b50a 100644 --- a/tools/lib/lockdep/tests/unlock_balance.c +++ b/tools/lib/lockdep/tests/unlock_balance.c | |||
@@ -10,4 +10,6 @@ void main(void) | |||
10 | pthread_mutex_lock(&a); | 10 | pthread_mutex_lock(&a); |
11 | pthread_mutex_unlock(&a); | 11 | pthread_mutex_unlock(&a); |
12 | pthread_mutex_unlock(&a); | 12 | pthread_mutex_unlock(&a); |
13 | |||
14 | pthread_mutex_destroy(&a); | ||
13 | } | 15 | } |
diff --git a/tools/lib/lockdep/tests/unlock_balance.sh b/tools/lib/lockdep/tests/unlock_balance.sh new file mode 100644 index 000000000000..c6e3952303fe --- /dev/null +++ b/tools/lib/lockdep/tests/unlock_balance.sh | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/bin/bash | ||
2 | grep -q 'WARNING: bad unlock balance detected' | ||