History

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

Linus Torvalds committed 7 years ago

Commit 1eefdec2 parents 684019d 80eb86526 files · +131 −53Browse files

Unified · Split

26 files
  1. include/linux/lockdep.h +0 −2
  2. kernel/locking/lockdep.c +43 −33
  3. kernel/sched/fair.c +1 −3
  4. tools/lib/lockdep/include/liblockdep/common.h +1 −0
  5. tools/lib/lockdep/include/liblockdep/mutex.h +1 −0
  6. tools/lib/lockdep/include/liblockdep/rwlock.h +3 −3
  7. tools/lib/lockdep/lockdep.c +5 −0
  8. tools/lib/lockdep/run_tests.sh +27 −12
  9. tools/lib/lockdep/tests/AA.sh +2 −0
  10. tools/lib/lockdep/tests/ABA.sh +2 −0
  11. tools/lib/lockdep/tests/ABBA.c +3 −0
  12. tools/lib/lockdep/tests/ABBA.sh +2 −0
  13. tools/lib/lockdep/tests/ABBA_2threads.sh +2 −0
  14. tools/lib/lockdep/tests/ABBCCA.c +4 −0
  15. tools/lib/lockdep/tests/ABBCCA.sh +2 −0
  16. tools/lib/lockdep/tests/ABBCCDDA.c +5 −0
  17. tools/lib/lockdep/tests/ABBCCDDA.sh +2 −0
  18. tools/lib/lockdep/tests/ABCABC.c +4 −0
  19. tools/lib/lockdep/tests/ABCABC.sh +2 −0
  20. tools/lib/lockdep/tests/ABCDBCDA.c +5 −0
  21. tools/lib/lockdep/tests/ABCDBCDA.sh +2 −0
  22. tools/lib/lockdep/tests/ABCDBDDA.c +5 −0
  23. tools/lib/lockdep/tests/ABCDBDDA.sh +2 −0
  24. tools/lib/lockdep/tests/WW.sh +2 −0
  25. tools/lib/lockdep/tests/unlock_balance.c +2 −0
  26. tools/lib/lockdep/tests/unlock_balance.sh +2 −0
include/linux/lockdep.h+0−2
@@ -97,8 +97,6 @@ struct lock_class { · 96 unmodified lines
9797 * Generation counter, when doing certain classes of graph walking,
9898 * to ensure that we check one node only once:
9999 */
100− unsigned int version;
101−
102100 int name_version;
103101 const char *name;
104102
kernel/locking/lockdep.c+43−33
@@ -138,6 +138,9 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; · 137 unmodified lines
138138 * get freed - this significantly simplifies the debugging code.
139139 */
140140 unsigned long nr_lock_classes;
141+#ifndef CONFIG_DEBUG_LOCKDEP
142+static
143+#endif
141144 struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
142145
143146 static inline struct lock_class *hlock_class(struct held_lock *hlock)
@@ -626,7 +629,8 @@ static int static_obj(void *obj) · 482 unmodified lines
626629
627630 /*
628631 * 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.
630634 */
631635 static int count_matching_names(struct lock_class *new_class)
632636 {
@@ -636,7 +640,7 @@ static int count_matching_names(struct lock_class *new_class) · 3 unmodified lines
636640 if (!new_class->name)
637641 return 0;
638642
639− list_for_each_entry_rcu(class, &all_lock_classes, lock_entry) {
643+ list_for_each_entry(class, &all_lock_classes, lock_entry) {
640644 if (new_class->key - new_class->subclass == class->key)
641645 return class->name_version;
642646 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) · 146 unmodified lines
789793 class->key = key;
790794 class->name = lock->name;
791795 class->subclass = subclass;
792− INIT_LIST_HEAD(&class->lock_entry);
793796 INIT_LIST_HEAD(&class->locks_before);
794797 INIT_LIST_HEAD(&class->locks_after);
795798 class->name_version = count_matching_names(class);
@@ -801,7 +804,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) · 5 unmodified lines
801804 /*
802805 * Add it to the global list of classes:
803806 */
804− list_add_tail_rcu(&class->lock_entry, &all_lock_classes);
807+ list_add_tail(&class->lock_entry, &all_lock_classes);
805808
806809 if (verbose(class)) {
807810 graph_unlock();
@@ -3088,7 +3091,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, · 2280 unmodified lines
30883091 /*
30893092 * Initialize a lock instance's lock-class mapping info:
30903093 */
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,
30923095 struct lock_class_key *key, int subclass)
30933096 {
30943097 int i;
@@ -3144,12 +3147,6 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, · 49 unmodified lines
31443147 raw_local_irq_restore(flags);
31453148 }
31463149 }
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−}
31533150 EXPORT_SYMBOL_GPL(lockdep_init_map);
31543151
31553152 struct lock_class_key __lockdep_no_validate__;
@@ -4126,6 +4123,9 @@ void lockdep_reset(void) · 970 unmodified lines
41264123 raw_local_irq_restore(flags);
41274124 }
41284125
4126+/*
4127+ * Remove all references to a lock class. The caller must hold the graph lock.
4128+ */
41294129 static void zap_class(struct lock_class *class)
41304130 {
41314131 int i;
@@ -4142,7 +4142,7 @@ static void zap_class(struct lock_class *class) · 10 unmodified lines
41424142 * Unhash the class and remove it from the all_lock_classes list:
41434143 */
41444144 hlist_del_rcu(&class->hash_entry);
4145− list_del_rcu(&class->lock_entry);
4145+ list_del(&class->lock_entry);
41464146
41474147 RCU_INIT_POINTER(class->key, NULL);
41484148 RCU_INIT_POINTER(class->name, NULL);
@@ -4204,15 +4204,36 @@ void lockdep_free_key_range(void *start, unsigned long size) · 55 unmodified lines
42044204 */
42054205 }
42064206
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)
42084213 {
42094214 struct lock_class *class;
42104215 struct hlist_head *head;
4211− unsigned long flags;
42124216 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;
42144234
42154235 raw_local_irq_save(flags);
4236+ locked = graph_lock();
42164237
42174238 /*
42184239 * Remove all classes this lock might have:
@@ -4229,25 +4250,14 @@ void lockdep_reset_lock(struct lockdep_map *lock) · 10 unmodified lines
42294250 * Debug check: in the end all mapped classes should
42304251 * be gone.
42314252 */
4232− locked = graph_lock();
4233− for (i = 0; i < CLASSHASH_SIZE; i++) {
4234− head = classhash_table + i;
4235− hlist_for_each_entry_rcu(class, head, hash_entry) {
4236− int match = 0;
4237−
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− }
4253+ if (unlikely(lock_class_cache_is_registered(lock))) {
4254+ if (debug_locks_off_graph_unlock()) {
4255+ /*
4256+ * We all just reset everything, how did it match?
4257+ */
4258+ WARN_ON(1);
42504259 }
4260+ goto out_restore;
42514261 }
42524262 if (locked)
42534263 graph_unlock();
kernel/sched/fair.c+1−3
@@ -9533,9 +9533,7 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) · 9532 unmodified lines
95339533 return false;
95349534 }
95359535
9536− /*
9537− * barrier, pairs with nohz_balance_enter_idle(), ensures ...
9538− */
9536+ /* could be _relaxed() */
95399537 flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu));
95409538 if (!(flags & NOHZ_KICK_MASK))
95419539 return false;
tools/lib/lockdep/include/liblockdep/common.h+1−0
@@ -44,6 +44,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, · 43 unmodified lines
4444 struct lockdep_map *nest_lock, unsigned long ip);
4545 void lock_release(struct lockdep_map *lock, int nested,
4646 unsigned long ip);
47+void lockdep_reset_lock(struct lockdep_map *lock);
4748 extern void debug_check_no_locks_freed(const void *from, unsigned long len);
4849
4950 #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
tools/lib/lockdep/include/liblockdep/mutex.h+1−0
@@ -54,6 +54,7 @@ static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *l · 53 unmodified lines
5454
5555 static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock)
5656 {
57+ lockdep_reset_lock(&lock->dep_map);
5758 return pthread_mutex_destroy(&lock->mutex);
5859 }
5960
tools/lib/lockdep/include/liblockdep/rwlock.h+3−3
@@ -60,10 +60,10 @@ static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_ · 59 unmodified lines
6060 return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0;
6161 }
6262
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)
6464 {
6565 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;
6767 }
6868
6969 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) · 9 unmodified lines
7979 #define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock
8080 #define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock
8181 #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
8383 #define pthread_rwlock_destroy liblockdep_rwlock_destroy
8484
8585 #endif
tools/lib/lockdep/lockdep.c+5−0
@@ -15,6 +15,11 @@ u32 prandom_u32(void) · 14 unmodified lines
1515 abort();
1616 }
1717
18+void print_irqtrace_events(struct task_struct *curr)
19+{
20+ abort();
21+}
22+
1823 static struct new_utsname *init_utsname(void)
1924 {
2025 static struct new_utsname n = (struct new_utsname) {
tools/lib/lockdep/run_tests.sh+27−12
@@ -1,32 +1,47 @@
11 #! /bin/bash
22 # SPDX-License-Identifier: GPL-2.0
33
4−make &> /dev/null
4+if ! make >/dev/null; then
5+ echo "Building liblockdep failed."
6+ echo "FAILED!"
7+ exit 1
8+fi
59
6−for i in `ls tests/*.c`; do
10+find tests -name '*.c' | sort | while read -r i; do
711 testname=$(basename "$i" .c)
8− gcc -o tests/$testname -pthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null
912 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
1115 echo "PASSED!"
1216 else
1317 echo "FAILED!"
1418 fi
15− if [ -f "tests/$testname" ]; then
16− rm tests/$testname
17− fi
19+ rm -f "tests/$testname"
1820 done
1921
20−for i in `ls tests/*.c`; do
22+find tests -name '*.c' | sort | while read -r i; do
2123 testname=$(basename "$i" .c)
22− gcc -o tests/$testname -pthread -Iinclude $i &> /dev/null
2324 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
2528 echo "PASSED!"
2629 else
2730 echo "FAILED!"
2831 fi
29− if [ -f "tests/$testname" ]; then
30− rm tests/$testname
32+ rm -f "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!"
3145 fi
46+ rm -f "tests/$testname"
3247 done
tools/lib/lockdep/tests/AA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible recursive locking detected'
tools/lib/lockdep/tests/ABA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible recursive locking detected'
tools/lib/lockdep/tests/ABBA.c+3−0
@@ -11,4 +11,7 @@ void main(void) · 10 unmodified lines
1111
1212 LOCK_UNLOCK_2(a, b);
1313 LOCK_UNLOCK_2(b, a);
14+
15+ pthread_mutex_destroy(&b);
16+ pthread_mutex_destroy(&a);
1417 }
tools/lib/lockdep/tests/ABBA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABBA_2threads.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABBCCA.c+4−0
@@ -13,4 +13,8 @@ void main(void) · 12 unmodified lines
1313 LOCK_UNLOCK_2(a, b);
1414 LOCK_UNLOCK_2(b, c);
1515 LOCK_UNLOCK_2(c, a);
16+
17+ pthread_mutex_destroy(&c);
18+ pthread_mutex_destroy(&b);
19+ pthread_mutex_destroy(&a);
1620 }
tools/lib/lockdep/tests/ABBCCA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABBCCDDA.c+5−0
@@ -15,4 +15,9 @@ void main(void) · 14 unmodified lines
1515 LOCK_UNLOCK_2(b, c);
1616 LOCK_UNLOCK_2(c, d);
1717 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);
1823 }
tools/lib/lockdep/tests/ABBCCDDA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABCABC.c+4−0
@@ -13,4 +13,8 @@ void main(void) · 12 unmodified lines
1313 LOCK_UNLOCK_2(a, b);
1414 LOCK_UNLOCK_2(c, a);
1515 LOCK_UNLOCK_2(b, c);
16+
17+ pthread_mutex_destroy(&c);
18+ pthread_mutex_destroy(&b);
19+ pthread_mutex_destroy(&a);
1620 }
tools/lib/lockdep/tests/ABCABC.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABCDBCDA.c+5−0
@@ -15,4 +15,9 @@ void main(void) · 14 unmodified lines
1515 LOCK_UNLOCK_2(c, d);
1616 LOCK_UNLOCK_2(b, c);
1717 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);
1823 }
tools/lib/lockdep/tests/ABCDBCDA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/ABCDBDDA.c+5−0
@@ -15,4 +15,9 @@ void main(void) · 14 unmodified lines
1515 LOCK_UNLOCK_2(c, d);
1616 LOCK_UNLOCK_2(b, d);
1717 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);
1823 }
tools/lib/lockdep/tests/ABCDBDDA.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible circular locking dependency detected'
tools/lib/lockdep/tests/WW.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: possible recursive locking detected'
tools/lib/lockdep/tests/unlock_balance.c+2−0
@@ -10,4 +10,6 @@ void main(void) · 9 unmodified lines
1010 pthread_mutex_lock(&a);
1111 pthread_mutex_unlock(&a);
1212 pthread_mutex_unlock(&a);
13+
14+ pthread_mutex_destroy(&a);
1315 }
tools/lib/lockdep/tests/unlock_balance.sh+2−0
@@ -0,0 +1,2 @@
1+#!/bin/bash
2+grep -q 'WARNING: bad unlock balance detected'