aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-12-26 17:25:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-26 17:25:52 -0500
commit1eefdec18eded41833401cfd64749643ff72e7da (patch)
treecf9d35939e239b7d1ed3194bec7f4d51409c2d50
parent684019dd1f0092b4ffce4958c84aff0891deac83 (diff)
parent80eb865768703c0f85a0603762742ae1dedf21f0 (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
-rw-r--r--include/linux/lockdep.h2
-rw-r--r--kernel/locking/lockdep.c76
-rw-r--r--kernel/sched/fair.c4
-rw-r--r--tools/lib/lockdep/include/liblockdep/common.h1
-rw-r--r--tools/lib/lockdep/include/liblockdep/mutex.h1
-rw-r--r--tools/lib/lockdep/include/liblockdep/rwlock.h6
-rw-r--r--tools/lib/lockdep/lockdep.c5
-rwxr-xr-xtools/lib/lockdep/run_tests.sh39
-rw-r--r--tools/lib/lockdep/tests/AA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABBA.c3
-rw-r--r--tools/lib/lockdep/tests/ABBA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABBA_2threads.sh2
-rw-r--r--tools/lib/lockdep/tests/ABBCCA.c4
-rw-r--r--tools/lib/lockdep/tests/ABBCCA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABBCCDDA.c5
-rw-r--r--tools/lib/lockdep/tests/ABBCCDDA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABCABC.c4
-rw-r--r--tools/lib/lockdep/tests/ABCABC.sh2
-rw-r--r--tools/lib/lockdep/tests/ABCDBCDA.c5
-rw-r--r--tools/lib/lockdep/tests/ABCDBCDA.sh2
-rw-r--r--tools/lib/lockdep/tests/ABCDBDDA.c5
-rw-r--r--tools/lib/lockdep/tests/ABCDBDDA.sh2
-rw-r--r--tools/lib/lockdep/tests/WW.sh2
-rw-r--r--tools/lib/lockdep/tests/unlock_balance.c2
-rw-r--r--tools/lib/lockdep/tests/unlock_balance.sh2
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 */
140unsigned long nr_lock_classes; 140unsigned long nr_lock_classes;
141#ifndef CONFIG_DEBUG_LOCKDEP
142static
143#endif
141struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; 144struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
142 145
143static inline struct lock_class *hlock_class(struct held_lock *hlock) 146static 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 */
631static int count_matching_names(struct lock_class *new_class) 635static 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 */
3091static void __lockdep_init_map(struct lockdep_map *lock, const char *name, 3094void 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
3148void 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}
3153EXPORT_SYMBOL_GPL(lockdep_init_map); 3150EXPORT_SYMBOL_GPL(lockdep_init_map);
3154 3151
3155struct lock_class_key __lockdep_no_validate__; 3152struct 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 */
4129static void zap_class(struct lock_class *class) 4129static 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
4207void 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 */
4212static 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
4229void 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);
45void lock_release(struct lockdep_map *lock, int nested, 45void lock_release(struct lockdep_map *lock, int nested,
46 unsigned long ip); 46 unsigned long ip);
47void lockdep_reset_lock(struct lockdep_map *lock);
47extern void debug_check_no_locks_freed(const void *from, unsigned long len); 48extern 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
55static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) 55static 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
63static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock) 63static 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
69static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) 69static 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
18void print_irqtrace_events(struct task_struct *curr)
19{
20 abort();
21}
22
18static struct new_utsname *init_utsname(void) 23static 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
4make &> /dev/null 4if ! make >/dev/null; then
5 echo "Building liblockdep failed."
6 echo "FAILED!"
7 exit 1
8fi
5 9
6for i in `ls tests/*.c`; do 10find 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
18done 20done
19 21
20for i in `ls tests/*.c`; do 22find 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 33done
34
35find 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"
32done 47done
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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -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
2grep -q 'WARNING: bad unlock balance detected'