mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	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
This commit is contained in:
		
						commit
						1eefdec18e
					
				
					 26 changed files with 132 additions and 54 deletions
				
			
		|  | @ -97,8 +97,6 @@ struct lock_class { | ||||||
| 	 * Generation counter, when doing certain classes of graph walking, | 	 * Generation counter, when doing certain classes of graph walking, | ||||||
| 	 * to ensure that we check one node only once: | 	 * to ensure that we check one node only once: | ||||||
| 	 */ | 	 */ | ||||||
| 	unsigned int			version; |  | ||||||
| 
 |  | ||||||
| 	int				name_version; | 	int				name_version; | ||||||
| 	const char			*name; | 	const char			*name; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -138,6 +138,9 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; | ||||||
|  * get freed - this significantly simplifies the debugging code. |  * get freed - this significantly simplifies the debugging code. | ||||||
|  */ |  */ | ||||||
| unsigned long nr_lock_classes; | unsigned long nr_lock_classes; | ||||||
|  | #ifndef CONFIG_DEBUG_LOCKDEP | ||||||
|  | static | ||||||
|  | #endif | ||||||
| struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; | struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; | ||||||
| 
 | 
 | ||||||
| static inline struct lock_class *hlock_class(struct held_lock *hlock) | static inline struct lock_class *hlock_class(struct held_lock *hlock) | ||||||
|  | @ -626,7 +629,8 @@ static int static_obj(void *obj) | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * To make lock name printouts unique, we calculate a unique |  * 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) | static int count_matching_names(struct lock_class *new_class) | ||||||
| { | { | ||||||
|  | @ -636,7 +640,7 @@ static int count_matching_names(struct lock_class *new_class) | ||||||
| 	if (!new_class->name) | 	if (!new_class->name) | ||||||
| 		return 0; | 		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) | 		if (new_class->key - new_class->subclass == class->key) | ||||||
| 			return class->name_version; | 			return class->name_version; | ||||||
| 		if (class->name && !strcmp(class->name, new_class->name)) | 		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) | ||||||
| 	class->key = key; | 	class->key = key; | ||||||
| 	class->name = lock->name; | 	class->name = lock->name; | ||||||
| 	class->subclass = subclass; | 	class->subclass = subclass; | ||||||
| 	INIT_LIST_HEAD(&class->lock_entry); |  | ||||||
| 	INIT_LIST_HEAD(&class->locks_before); | 	INIT_LIST_HEAD(&class->locks_before); | ||||||
| 	INIT_LIST_HEAD(&class->locks_after); | 	INIT_LIST_HEAD(&class->locks_after); | ||||||
| 	class->name_version = count_matching_names(class); | 	class->name_version = count_matching_names(class); | ||||||
|  | @ -801,7 +804,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Add it to the global list of classes: | 	 * 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)) { | 	if (verbose(class)) { | ||||||
| 		graph_unlock(); | 		graph_unlock(); | ||||||
|  | @ -3088,7 +3091,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | ||||||
| /*
 | /*
 | ||||||
|  * Initialize a lock instance's lock-class mapping info: |  * 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) | 		      struct lock_class_key *key, int subclass) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  | @ -3144,12 +3147,6 @@ static void __lockdep_init_map(struct lockdep_map *lock, const char *name, | ||||||
| 		raw_local_irq_restore(flags); | 		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); | EXPORT_SYMBOL_GPL(lockdep_init_map); | ||||||
| 
 | 
 | ||||||
| struct lock_class_key __lockdep_no_validate__; | struct lock_class_key __lockdep_no_validate__; | ||||||
|  | @ -4126,6 +4123,9 @@ void lockdep_reset(void) | ||||||
| 	raw_local_irq_restore(flags); | 	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) | static void zap_class(struct lock_class *class) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  | @ -4142,7 +4142,7 @@ static void zap_class(struct lock_class *class) | ||||||
| 	 * Unhash the class and remove it from the all_lock_classes list: | 	 * Unhash the class and remove it from the all_lock_classes list: | ||||||
| 	 */ | 	 */ | ||||||
| 	hlist_del_rcu(&class->hash_entry); | 	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->key, NULL); | ||||||
| 	RCU_INIT_POINTER(class->name, NULL); | 	RCU_INIT_POINTER(class->name, NULL); | ||||||
|  | @ -4204,15 +4204,36 @@ 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 lock_class *class; | ||||||
| 	struct hlist_head *head; | 	struct hlist_head *head; | ||||||
| 	unsigned long flags; |  | ||||||
| 	int i, j; | 	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); | 	raw_local_irq_save(flags); | ||||||
|  | 	locked = graph_lock(); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Remove all classes this lock might have: | 	 * Remove all classes this lock might have: | ||||||
|  | @ -4229,25 +4250,14 @@ void lockdep_reset_lock(struct lockdep_map *lock) | ||||||
| 	 * Debug check: in the end all mapped classes should | 	 * Debug check: in the end all mapped classes should | ||||||
| 	 * be gone. | 	 * be gone. | ||||||
| 	 */ | 	 */ | ||||||
| 	locked = graph_lock(); | 	if (unlikely(lock_class_cache_is_registered(lock))) { | ||||||
| 	for (i = 0; i < CLASSHASH_SIZE; i++) { | 		if (debug_locks_off_graph_unlock()) { | ||||||
| 		head = classhash_table + i; | 			/*
 | ||||||
| 		hlist_for_each_entry_rcu(class, head, hash_entry) { | 			 * We all just reset everything, how did it match? | ||||||
| 			int match = 0; | 			 */ | ||||||
| 
 | 			WARN_ON(1); | ||||||
| 			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; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
|  | 		goto out_restore; | ||||||
| 	} | 	} | ||||||
| 	if (locked) | 	if (locked) | ||||||
| 		graph_unlock(); | 		graph_unlock(); | ||||||
|  |  | ||||||
|  | @ -9533,9 +9533,7 @@ static bool nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/* could be _relaxed() */ | ||||||
| 	 * barrier, pairs with nohz_balance_enter_idle(), ensures ... |  | ||||||
| 	 */ |  | ||||||
| 	flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu)); | 	flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(this_cpu)); | ||||||
| 	if (!(flags & NOHZ_KICK_MASK)) | 	if (!(flags & NOHZ_KICK_MASK)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | ||||||
| 			struct lockdep_map *nest_lock, unsigned long ip); | 			struct lockdep_map *nest_lock, unsigned long ip); | ||||||
| void lock_release(struct lockdep_map *lock, int nested, | void lock_release(struct lockdep_map *lock, int nested, | ||||||
| 			unsigned long ip); | 			unsigned long ip); | ||||||
|  | void lockdep_reset_lock(struct lockdep_map *lock); | ||||||
| extern void debug_check_no_locks_freed(const void *from, unsigned long len); | extern void debug_check_no_locks_freed(const void *from, unsigned long len); | ||||||
| 
 | 
 | ||||||
| #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ | #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ | ||||||
|  |  | ||||||
|  | @ -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) | static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) | ||||||
| { | { | ||||||
|  | 	lockdep_reset_lock(&lock->dep_map); | ||||||
| 	return pthread_mutex_destroy(&lock->mutex); | 	return pthread_mutex_destroy(&lock->mutex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -60,10 +60,10 @@ static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_ | ||||||
| 	return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; | 	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_); | 	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) | 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_unlock		liblockdep_pthread_rwlock_unlock | ||||||
| #define pthread_rwlock_wrlock		liblockdep_pthread_rwlock_wrlock | #define pthread_rwlock_wrlock		liblockdep_pthread_rwlock_wrlock | ||||||
| #define pthread_rwlock_tryrdlock	liblockdep_pthread_rwlock_tryrdlock | #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 | #define pthread_rwlock_destroy		liblockdep_rwlock_destroy | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -15,6 +15,11 @@ u32 prandom_u32(void) | ||||||
| 	abort(); | 	abort(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void print_irqtrace_events(struct task_struct *curr) | ||||||
|  | { | ||||||
|  | 	abort(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static struct new_utsname *init_utsname(void) | static struct new_utsname *init_utsname(void) | ||||||
| { | { | ||||||
| 	static struct new_utsname n = (struct new_utsname) { | 	static struct new_utsname n = (struct new_utsname) { | ||||||
|  |  | ||||||
|  | @ -1,32 +1,47 @@ | ||||||
| #! /bin/bash | #! /bin/bash | ||||||
| # SPDX-License-Identifier: GPL-2.0 | # 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 | find tests -name '*.c' | sort | while read -r i; do | ||||||
| 	testname=$(basename "$i" .c) | 	testname=$(basename "$i" .c) | ||||||
| 	gcc -o tests/$testname -pthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null |  | ||||||
| 	echo -ne "$testname... " | 	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 | "tests/${testname}.sh"; then | ||||||
| 		echo "PASSED!" | 		echo "PASSED!" | ||||||
| 	else | 	else | ||||||
| 		echo "FAILED!" | 		echo "FAILED!" | ||||||
| 	fi | 	fi | ||||||
| 	if [ -f "tests/$testname" ]; then | 	rm -f "tests/$testname" | ||||||
| 		rm tests/$testname |  | ||||||
| 	fi |  | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| for i in `ls tests/*.c`; do | find tests -name '*.c' | sort | while read -r i; do | ||||||
| 	testname=$(basename "$i" .c) | 	testname=$(basename "$i" .c) | ||||||
| 	gcc -o tests/$testname -pthread -Iinclude $i &> /dev/null |  | ||||||
| 	echo -ne "(PRELOAD) $testname... " | 	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 | | ||||||
|  | 		"tests/${testname}.sh"; then | ||||||
| 		echo "PASSED!" | 		echo "PASSED!" | ||||||
| 	else | 	else | ||||||
| 		echo "FAILED!" | 		echo "FAILED!" | ||||||
| 	fi | 	fi | ||||||
| 	if [ -f "tests/$testname" ]; then | 	rm -f "tests/$testname" | ||||||
| 		rm tests/$testname | done | ||||||
| 	fi | 
 | ||||||
|  | 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 | done | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/AA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/AA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible recursive locking detected' | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible recursive locking detected' | ||||||
|  | @ -11,4 +11,7 @@ void main(void) | ||||||
| 
 | 
 | ||||||
| 	LOCK_UNLOCK_2(a, b); | 	LOCK_UNLOCK_2(a, b); | ||||||
| 	LOCK_UNLOCK_2(b, a); | 	LOCK_UNLOCK_2(b, a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABBA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABBA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABBA_2threads.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABBA_2threads.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
|  | @ -13,4 +13,8 @@ void main(void) | ||||||
| 	LOCK_UNLOCK_2(a, b); | 	LOCK_UNLOCK_2(a, b); | ||||||
| 	LOCK_UNLOCK_2(b, c); | 	LOCK_UNLOCK_2(b, c); | ||||||
| 	LOCK_UNLOCK_2(c, a); | 	LOCK_UNLOCK_2(c, a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&c); | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABBCCA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABBCCA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
|  | @ -15,4 +15,9 @@ void main(void) | ||||||
| 	LOCK_UNLOCK_2(b, c); | 	LOCK_UNLOCK_2(b, c); | ||||||
| 	LOCK_UNLOCK_2(c, d); | 	LOCK_UNLOCK_2(c, d); | ||||||
| 	LOCK_UNLOCK_2(d, a); | 	LOCK_UNLOCK_2(d, a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&d); | ||||||
|  | 	pthread_mutex_destroy(&c); | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABBCCDDA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABBCCDDA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
|  | @ -13,4 +13,8 @@ void main(void) | ||||||
| 	LOCK_UNLOCK_2(a, b); | 	LOCK_UNLOCK_2(a, b); | ||||||
| 	LOCK_UNLOCK_2(c, a); | 	LOCK_UNLOCK_2(c, a); | ||||||
| 	LOCK_UNLOCK_2(b, c); | 	LOCK_UNLOCK_2(b, c); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&c); | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABCABC.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABCABC.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
|  | @ -15,4 +15,9 @@ void main(void) | ||||||
| 	LOCK_UNLOCK_2(c, d); | 	LOCK_UNLOCK_2(c, d); | ||||||
| 	LOCK_UNLOCK_2(b, c); | 	LOCK_UNLOCK_2(b, c); | ||||||
| 	LOCK_UNLOCK_2(d, a); | 	LOCK_UNLOCK_2(d, a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&d); | ||||||
|  | 	pthread_mutex_destroy(&c); | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABCDBCDA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABCDBCDA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
|  | @ -15,4 +15,9 @@ void main(void) | ||||||
| 	LOCK_UNLOCK_2(c, d); | 	LOCK_UNLOCK_2(c, d); | ||||||
| 	LOCK_UNLOCK_2(b, d); | 	LOCK_UNLOCK_2(b, d); | ||||||
| 	LOCK_UNLOCK_2(d, a); | 	LOCK_UNLOCK_2(d, a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&d); | ||||||
|  | 	pthread_mutex_destroy(&c); | ||||||
|  | 	pthread_mutex_destroy(&b); | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/ABCDBDDA.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/ABCDBDDA.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible circular locking dependency detected' | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/WW.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/WW.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: possible recursive locking detected' | ||||||
|  | @ -10,4 +10,6 @@ void main(void) | ||||||
| 	pthread_mutex_lock(&a); | 	pthread_mutex_lock(&a); | ||||||
| 	pthread_mutex_unlock(&a); | 	pthread_mutex_unlock(&a); | ||||||
| 	pthread_mutex_unlock(&a); | 	pthread_mutex_unlock(&a); | ||||||
|  | 
 | ||||||
|  | 	pthread_mutex_destroy(&a); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								tools/lib/lockdep/tests/unlock_balance.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tools/lib/lockdep/tests/unlock_balance.sh
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | grep -q 'WARNING: bad unlock balance detected' | ||||||
		Loading…
	
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds