From 2421b7f3573babfe1673a5ffee1677a5013e6df1 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Mon, 19 Nov 2018 13:55:10 -0500 Subject: [PATCH 01/15] locking/lockdep: Remove ::version from lock_class structure It turns out the version field in the lock_class structure isn't used anywhere. Just remove it. Signed-off-by: Waiman Long Signed-off-by: Peter Zijlstra (Intel) Cc: Andrew Morton Cc: Andrey Ryabinin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Petr Mladek Cc: Sasha Levin Cc: Sergey Senozhatsky Cc: Tejun Heo Cc: Thomas Gleixner Cc: Will Deacon Cc: iommu@lists.linux-foundation.org Cc: kasan-dev@googlegroups.com Link: https://lkml.kernel.org/r/1542653726-5655-2-git-send-email-longman@redhat.com Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 2 -- 1 file changed, 2 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 { * Generation counter, when doing certain classes of graph walking, * to ensure that we check one node only once: */ - unsigned int version; - int name_version; const char *name; From da087b2229618f78ecea5c203fed8ba2245de636 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:25 -0800 Subject: [PATCH 02/15] tools/lib/lockdep/tests: Display compiler warning and error messages If compilation of liblockdep fails, display an error message and exit immediately. Display compiler warning and error messages that are generated while building a test. Only run a test if compilation of it succeeded. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-2-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/run_tests.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index 2e570a188f16..9f31f84e7fac 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh @@ -1,13 +1,17 @@ #! /bin/bash # SPDX-License-Identifier: GPL-2.0 -make &> /dev/null +if ! make >/dev/null; then + echo "Building liblockdep failed." + echo "FAILED!" + exit 1 +fi for i in `ls tests/*.c`; do testname=$(basename "$i" .c) - gcc -o tests/$testname -pthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null echo -ne "$testname... " - if [ $(timeout 1 ./tests/$testname 2>&1 | wc -l) -gt 0 ]; then + if gcc -o "tests/$testname" -pthread "$i" liblockdep.a -Iinclude -D__USE_LIBLOCKDEP && + [ "$(timeout 1 "./tests/$testname" 2>&1 | wc -l)" -gt 0 ]; then echo "PASSED!" else echo "FAILED!" @@ -19,9 +23,9 @@ done for i in `ls tests/*.c`; do testname=$(basename "$i" .c) - gcc -o tests/$testname -pthread -Iinclude $i &> /dev/null echo -ne "(PRELOAD) $testname... " - if [ $(timeout 1 ./lockdep ./tests/$testname 2>&1 | wc -l) -gt 0 ]; then + if gcc -o "tests/$testname" -pthread -Iinclude "$i" && + [ "$(timeout 1 ./lockdep "./tests/$testname" 2>&1 | wc -l)" -gt 0 ]; then echo "PASSED!" else echo "FAILED!" From 7e9798871a9186cb831cf693d7ff58085384ccbd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:26 -0800 Subject: [PATCH 03/15] tools/lib/lockdep/tests: Fix shellcheck warnings Use find instead of ls to avoid splitting filenames that contain spaces. Use rm -f instead of if ... then rm ...; fi. This patch addresses all shellcheck complaints about the run_tests.sh shell script. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-3-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/run_tests.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index 9f31f84e7fac..253719ee6377 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh @@ -7,7 +7,7 @@ if ! make >/dev/null; then exit 1 fi -for i in `ls tests/*.c`; do +find tests -name '*.c' | sort | while read -r i; do testname=$(basename "$i" .c) echo -ne "$testname... " if gcc -o "tests/$testname" -pthread "$i" liblockdep.a -Iinclude -D__USE_LIBLOCKDEP && @@ -16,12 +16,10 @@ for i in `ls tests/*.c`; do else echo "FAILED!" fi - if [ -f "tests/$testname" ]; then - rm tests/$testname - fi + rm -f "tests/$testname" done -for i in `ls tests/*.c`; do +find tests -name '*.c' | sort | while read -r i; do testname=$(basename "$i" .c) echo -ne "(PRELOAD) $testname... " if gcc -o "tests/$testname" -pthread -Iinclude "$i" && @@ -30,7 +28,5 @@ for i in `ls tests/*.c`; do else echo "FAILED!" fi - if [ -f "tests/$testname" ]; then - rm tests/$testname - fi + rm -f "tests/$testname" done From 5ecb8e94b494af0df8de4ca9b9ef88d87b30a9c1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:27 -0800 Subject: [PATCH 04/15] tools/lib/lockdep/tests: Improve testing accuracy Instead of checking whether the tests produced any output, check the output itself. This patch avoids that e.g. debug output causes the message "PASSED!" to be reported for failed tests. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-4-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/run_tests.sh | 5 +++-- tools/lib/lockdep/tests/AA.sh | 2 ++ tools/lib/lockdep/tests/ABA.sh | 2 ++ tools/lib/lockdep/tests/ABBA.sh | 2 ++ tools/lib/lockdep/tests/ABBA_2threads.sh | 2 ++ tools/lib/lockdep/tests/ABBCCA.sh | 2 ++ tools/lib/lockdep/tests/ABBCCDDA.sh | 2 ++ tools/lib/lockdep/tests/ABCABC.sh | 2 ++ tools/lib/lockdep/tests/ABCDBCDA.sh | 2 ++ tools/lib/lockdep/tests/ABCDBDDA.sh | 2 ++ tools/lib/lockdep/tests/WW.sh | 2 ++ tools/lib/lockdep/tests/unlock_balance.sh | 2 ++ 12 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tools/lib/lockdep/tests/AA.sh create mode 100644 tools/lib/lockdep/tests/ABA.sh create mode 100644 tools/lib/lockdep/tests/ABBA.sh create mode 100644 tools/lib/lockdep/tests/ABBA_2threads.sh create mode 100644 tools/lib/lockdep/tests/ABBCCA.sh create mode 100644 tools/lib/lockdep/tests/ABBCCDDA.sh create mode 100644 tools/lib/lockdep/tests/ABCABC.sh create mode 100644 tools/lib/lockdep/tests/ABCDBCDA.sh create mode 100644 tools/lib/lockdep/tests/ABCDBDDA.sh create mode 100644 tools/lib/lockdep/tests/WW.sh create mode 100644 tools/lib/lockdep/tests/unlock_balance.sh diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index 253719ee6377..bc36178329a8 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh @@ -11,7 +11,7 @@ find tests -name '*.c' | sort | while read -r i; do testname=$(basename "$i" .c) echo -ne "$testname... " if gcc -o "tests/$testname" -pthread "$i" liblockdep.a -Iinclude -D__USE_LIBLOCKDEP && - [ "$(timeout 1 "./tests/$testname" 2>&1 | wc -l)" -gt 0 ]; then + timeout 1 "tests/$testname" 2>&1 | "tests/${testname}.sh"; then echo "PASSED!" else echo "FAILED!" @@ -23,7 +23,8 @@ find tests -name '*.c' | sort | while read -r i; do testname=$(basename "$i" .c) echo -ne "(PRELOAD) $testname... " if gcc -o "tests/$testname" -pthread -Iinclude "$i" && - [ "$(timeout 1 ./lockdep "./tests/$testname" 2>&1 | wc -l)" -gt 0 ]; then + timeout 1 ./lockdep "tests/$testname" 2>&1 | + "tests/${testname}.sh"; then echo "PASSED!" else echo "FAILED!" 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 @@ +#!/bin/bash +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 @@ +#!/bin/bash +grep -q 'WARNING: possible recursive locking detected' 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 @@ +#!/bin/bash +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 @@ +#!/bin/bash +grep -q 'WARNING: possible circular locking dependency detected' 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 @@ +#!/bin/bash +grep -q 'WARNING: possible circular locking dependency detected' 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 @@ +#!/bin/bash +grep -q 'WARNING: possible circular locking dependency detected' 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 @@ +#!/bin/bash +grep -q 'WARNING: possible circular locking dependency detected' 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 @@ +#!/bin/bash +grep -q 'WARNING: possible circular locking dependency detected' 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 @@ +#!/bin/bash +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 @@ +#!/bin/bash +grep -q 'WARNING: possible recursive locking detected' 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 @@ +#!/bin/bash +grep -q 'WARNING: bad unlock balance detected' From 2b28a8609ec9891e37607ae20688b4ab34f2778c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:28 -0800 Subject: [PATCH 05/15] tools/lib/lockdep/tests: Run lockdep tests a second time under Valgrind This improves test coverage. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-5-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/run_tests.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index bc36178329a8..c8fbd0306960 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh @@ -31,3 +31,17 @@ find tests -name '*.c' | sort | while read -r i; do fi rm -f "tests/$testname" done + +find tests -name '*.c' | sort | while read -r i; do + testname=$(basename "$i" .c) + echo -ne "(PRELOAD + Valgrind) $testname... " + if gcc -o "tests/$testname" -pthread -Iinclude "$i" && + { timeout 10 valgrind --read-var-info=yes ./lockdep "./tests/$testname" >& "tests/${testname}.vg.out"; true; } && + "tests/${testname}.sh" < "tests/${testname}.vg.out" && + ! grep -Eq '(^==[0-9]*== (Invalid |Uninitialised ))|Mismatched free|Source and destination overlap| UME ' "tests/${testname}.vg.out"; then + echo "PASSED!" + else + echo "FAILED!" + fi + rm -f "tests/$testname" +done From 7f3c7952d111ac93573fb86f4d5aeff527a07fcc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:29 -0800 Subject: [PATCH 06/15] tools/lib/lockdep: Rename "trywlock" into "trywrlock" This patch avoids that the following compiler warning is reported while compiling the lockdep unit tests: include/liblockdep/rwlock.h: In function 'liblockdep_pthread_rwlock_trywlock': include/liblockdep/rwlock.h:66:9: warning: implicit declaration of function 'pthread_rwlock_trywlock'; did you mean 'pthread_rwlock_trywrlock'? [-Wimplicit-function-declaration] return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0; ^~~~~~~~~~~~~~~~~~~~~~~ pthread_rwlock_trywrlock Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Fixes: 5a52c9b480e0 ("liblockdep: Add public headers for pthread_rwlock_t implementation") Link: https://lkml.kernel.org/r/20181207011148.251812-6-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/include/liblockdep/rwlock.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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_ return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; } -static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock) +static inline int liblockdep_pthread_rwlock_trywrlock(liblockdep_pthread_rwlock_t *lock) { lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); - return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0; + return pthread_rwlock_trywrlock(&lock->rwlock) == 0 ? 1 : 0; } 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) #define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock #define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock #define pthread_rwlock_tryrdlock liblockdep_pthread_rwlock_tryrdlock -#define pthread_rwlock_trywlock liblockdep_pthread_rwlock_trywlock +#define pthread_rwlock_trywrlock liblockdep_pthread_rwlock_trywrlock #define pthread_rwlock_destroy liblockdep_rwlock_destroy #endif From ac862d9b2fd084b50ee7a332a35d8d8d3228ce09 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:30 -0800 Subject: [PATCH 07/15] tools/lib/lockdep: Add dummy print_irqtrace_events() implementation This patch avoids that linking against liblockdep fails due to no print_irqtrace_events() definition being available. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-7-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/lockdep.c | 5 +++++ 1 file changed, 5 insertions(+) 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) abort(); } +void print_irqtrace_events(struct task_struct *curr) +{ + abort(); +} + static struct new_utsname *init_utsname(void) { static struct new_utsname n = (struct new_utsname) { From 886adbed7ac19352315e9f1dd880360c7544d25c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:31 -0800 Subject: [PATCH 08/15] tools/lib/lockdep/tests: Test the lockdep_reset_lock() implementation This patch makes sure that the lockdep_reset_lock() function gets tested. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-8-bvanassche@acm.org Signed-off-by: Ingo Molnar --- tools/lib/lockdep/include/liblockdep/common.h | 1 + tools/lib/lockdep/include/liblockdep/mutex.h | 1 + tools/lib/lockdep/tests/ABBA.c | 3 +++ tools/lib/lockdep/tests/ABBCCA.c | 4 ++++ tools/lib/lockdep/tests/ABBCCDDA.c | 5 +++++ tools/lib/lockdep/tests/ABCABC.c | 4 ++++ tools/lib/lockdep/tests/ABCDBCDA.c | 5 +++++ tools/lib/lockdep/tests/ABCDBDDA.c | 5 +++++ tools/lib/lockdep/tests/unlock_balance.c | 2 ++ 9 files changed, 30 insertions(+) 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, struct lockdep_map *nest_lock, unsigned long ip); void lock_release(struct lockdep_map *lock, int nested, unsigned long ip); +void lockdep_reset_lock(struct lockdep_map *lock); extern void debug_check_no_locks_freed(const void *from, unsigned long len); #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 static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) { + lockdep_reset_lock(&lock->dep_map); return pthread_mutex_destroy(&lock->mutex); } 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) LOCK_UNLOCK_2(a, b); LOCK_UNLOCK_2(b, a); + + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) LOCK_UNLOCK_2(a, b); LOCK_UNLOCK_2(b, c); LOCK_UNLOCK_2(c, a); + + pthread_mutex_destroy(&c); + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) LOCK_UNLOCK_2(b, c); LOCK_UNLOCK_2(c, d); LOCK_UNLOCK_2(d, a); + + pthread_mutex_destroy(&d); + pthread_mutex_destroy(&c); + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) LOCK_UNLOCK_2(a, b); LOCK_UNLOCK_2(c, a); LOCK_UNLOCK_2(b, c); + + pthread_mutex_destroy(&c); + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) LOCK_UNLOCK_2(c, d); LOCK_UNLOCK_2(b, c); LOCK_UNLOCK_2(d, a); + + pthread_mutex_destroy(&d); + pthread_mutex_destroy(&c); + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) LOCK_UNLOCK_2(c, d); LOCK_UNLOCK_2(b, d); LOCK_UNLOCK_2(d, a); + + pthread_mutex_destroy(&d); + pthread_mutex_destroy(&c); + pthread_mutex_destroy(&b); + pthread_mutex_destroy(&a); } 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) pthread_mutex_lock(&a); pthread_mutex_unlock(&a); pthread_mutex_unlock(&a); + + pthread_mutex_destroy(&a); } From 1431a5d2cfa18d7006d9b0e7ab4548d9bb19ce55 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:32 -0800 Subject: [PATCH 09/15] locking/lockdep: Declare local symbols static This patch avoids that sparse complains about a missing declaration for the lock_classes array when building with CONFIG_DEBUG_LOCKDEP=n. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-9-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 1efada2dd9dd..7434a00b2b2f 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -138,6 +138,9 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; * get freed - this significantly simplifies the debugging code. */ unsigned long nr_lock_classes; +#ifndef CONFIG_DEBUG_LOCKDEP +static +#endif struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; static inline struct lock_class *hlock_class(struct held_lock *hlock) From d35568bdb6ce4be3f885f8f189bbde5adc7e0160 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:33 -0800 Subject: [PATCH 10/15] locking/lockdep: Inline __lockdep_init_map() Since the function __lockdep_init_map() only has one caller, inline it into its caller. This patch does not change any functionality. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-10-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 7434a00b2b2f..b5c8fcb6c070 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -3091,7 +3091,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, /* * Initialize a lock instance's lock-class mapping info: */ -static void __lockdep_init_map(struct lockdep_map *lock, const char *name, +void lockdep_init_map(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass) { int i; @@ -3147,12 +3147,6 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, raw_local_irq_restore(flags); } } - -void lockdep_init_map(struct lockdep_map *lock, const char *name, - struct lock_class_key *key, int subclass) -{ - __lockdep_init_map(lock, name, key, subclass); -} EXPORT_SYMBOL_GPL(lockdep_init_map); struct lock_class_key __lockdep_no_validate__; From 2904d9fa45d3ce7153f1e10d78c570ecf7f19c35 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:34 -0800 Subject: [PATCH 11/15] locking/lockdep: Introduce lock_class_cache_is_registered() This patch does not change any functionality but makes the lockdep_reset_lock() function easier to read. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-11-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index b5c8fcb6c070..81388d028ac7 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -4201,13 +4201,33 @@ void lockdep_free_key_range(void *start, unsigned long size) */ } -void lockdep_reset_lock(struct lockdep_map *lock) +/* + * Check whether any element of the @lock->class_cache[] array refers to a + * registered lock class. The caller must hold either the graph lock or the + * RCU read lock. + */ +static bool lock_class_cache_is_registered(struct lockdep_map *lock) { struct lock_class *class; struct hlist_head *head; - unsigned long flags; int i, j; - int locked; + + for (i = 0; i < CLASSHASH_SIZE; i++) { + head = classhash_table + i; + hlist_for_each_entry_rcu(class, head, hash_entry) { + for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) + if (lock->class_cache[j] == class) + return true; + } + } + return false; +} + +void lockdep_reset_lock(struct lockdep_map *lock) +{ + struct lock_class *class; + unsigned long flags; + int j, locked; raw_local_irq_save(flags); @@ -4227,24 +4247,14 @@ void lockdep_reset_lock(struct lockdep_map *lock) * be gone. */ locked = graph_lock(); - for (i = 0; i < CLASSHASH_SIZE; i++) { - head = classhash_table + i; - hlist_for_each_entry_rcu(class, head, hash_entry) { - int match = 0; - - for (j = 0; j < NR_LOCKDEP_CACHING_CLASSES; j++) - match |= class == lock->class_cache[j]; - - if (unlikely(match)) { - if (debug_locks_off_graph_unlock()) { - /* - * We all just reset everything, how did it match? - */ - WARN_ON(1); - } - goto out_restore; - } + if (unlikely(lock_class_cache_is_registered(lock))) { + if (debug_locks_off_graph_unlock()) { + /* + * We all just reset everything, how did it match? + */ + WARN_ON(1); } + goto out_restore; } if (locked) graph_unlock(); From a66b6922dc6a5ece60ea9326153da3b062977a4d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:35 -0800 Subject: [PATCH 12/15] locking/lockdep: Remove a superfluous INIT_LIST_HEAD() statement Initializing a list entry just before it is passed to list_add_tail_rcu() is not necessary because list_add_tail_rcu() overwrites the next and prev pointers anyway. Hence remove the INIT_LIST_HEAD() statement. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-12-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 81388d028ac7..346b5a1fd062 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -792,7 +792,6 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) class->key = key; class->name = lock->name; class->subclass = subclass; - INIT_LIST_HEAD(&class->lock_entry); INIT_LIST_HEAD(&class->locks_before); INIT_LIST_HEAD(&class->locks_after); class->name_version = count_matching_names(class); From 786fa29e9cb6810e21ab0d9c41a81d81d54d1d1b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:36 -0800 Subject: [PATCH 13/15] locking/lockdep: Make concurrent lockdep_reset_lock() calls safe Since zap_class() removes items from the all_lock_classes list and the classhash_table, protect all zap_class() calls against concurrent data structure modifications with the graph lock. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-13-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 346b5a1fd062..737d2dd3ea56 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -4122,6 +4122,9 @@ void lockdep_reset(void) raw_local_irq_restore(flags); } +/* + * Remove all references to a lock class. The caller must hold the graph lock. + */ static void zap_class(struct lock_class *class) { int i; @@ -4229,6 +4232,7 @@ void lockdep_reset_lock(struct lockdep_map *lock) int j, locked; raw_local_irq_save(flags); + locked = graph_lock(); /* * Remove all classes this lock might have: @@ -4245,7 +4249,6 @@ void lockdep_reset_lock(struct lockdep_map *lock) * Debug check: in the end all mapped classes should * be gone. */ - locked = graph_lock(); if (unlikely(lock_class_cache_is_registered(lock))) { if (debug_locks_off_graph_unlock()) { /* From fe27b0de8dfcdf8482558ce5d25e697fe74d851e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Dec 2018 17:11:37 -0800 Subject: [PATCH 14/15] locking/lockdep: Stop using RCU primitives to access 'all_lock_classes' Due to the previous patch all code that accesses the 'all_lock_classes' list holds the graph lock. Hence use regular list primitives instead of their RCU variants to access this list. Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra (Intel) Cc: Johannes Berg Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Waiman Long Cc: johannes.berg@intel.com Cc: tj@kernel.org Link: https://lkml.kernel.org/r/20181207011148.251812-14-bvanassche@acm.org Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 737d2dd3ea56..5c837a537273 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -629,7 +629,8 @@ static int static_obj(void *obj) /* * To make lock name printouts unique, we calculate a unique - * class->name_version generation counter: + * class->name_version generation counter. The caller must hold the graph + * lock. */ static int count_matching_names(struct lock_class *new_class) { @@ -639,7 +640,7 @@ static int count_matching_names(struct lock_class *new_class) if (!new_class->name) return 0; - list_for_each_entry_rcu(class, &all_lock_classes, lock_entry) { + list_for_each_entry(class, &all_lock_classes, lock_entry) { if (new_class->key - new_class->subclass == class->key) return class->name_version; if (class->name && !strcmp(class->name, new_class->name)) @@ -803,7 +804,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) /* * Add it to the global list of classes: */ - list_add_tail_rcu(&class->lock_entry, &all_lock_classes); + list_add_tail(&class->lock_entry, &all_lock_classes); if (verbose(class)) { graph_unlock(); @@ -4141,7 +4142,7 @@ static void zap_class(struct lock_class *class) * Unhash the class and remove it from the all_lock_classes list: */ hlist_del_rcu(&class->hash_entry); - list_del_rcu(&class->lock_entry); + list_del(&class->lock_entry); RCU_INIT_POINTER(class->key, NULL); RCU_INIT_POINTER(class->name, NULL); From 80eb865768703c0f85a0603762742ae1dedf21f0 Mon Sep 17 00:00:00 2001 From: Andrea Parri Date: Tue, 27 Nov 2018 12:01:10 +0100 Subject: [PATCH 15/15] sched/fair: Clean up comment in nohz_idle_balance() Concerning the comment associated to the atomic_fetch_andnot() in nohz_idle_balance(), Vincent explains [1]: "[...] the comment is useless and can be removed [...] it was referring to a line code above the comment that was present in a previous iteration of the patchset. This line disappeared in final version but the comment has stayed." So remove the comment. Vincent also points out that the full ordering associated to the atomic_fetch_andnot() primitive could be relaxed, but this patch insists on the current more conservative/fully ordered solution: "Performance" isn't a concern, stay away from "correctness"/subtle relaxed (re)ordering if possible..., just make sure not to confuse the next reader with misleading/out-of-date comments. [1] http://lkml.kernel.org/r/CAKfTPtBjA-oCBRkO6__npQwL3+HLjzk7riCcPU1R7YdO-EpuZg@mail.gmail.com Suggested-by: Vincent Guittot Signed-off-by: Andrea Parri Signed-off-by: Peter Zijlstra (Intel) Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20181127110110.5533-1-andrea.parri@amarulasolutions.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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) return false; } - /* - * barrier, pairs with nohz_balance_enter_idle(), ensures ... - */ + /* could be _relaxed() */ flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu)); if (!(flags & NOHZ_KICK_MASK)) return false;