diff options
Diffstat (limited to 'kernel/locking/lockdep.c')
| -rw-r--r-- | kernel/locking/lockdep.c | 25 | 
1 files changed, 13 insertions, 12 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index b71ad8d9f1c9..c1418b47f625 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -108,19 +108,21 @@ static inline void lockdep_lock(void)  {  	DEBUG_LOCKS_WARN_ON(!irqs_disabled()); +	__this_cpu_inc(lockdep_recursion);  	arch_spin_lock(&__lock);  	__owner = current; -	__this_cpu_inc(lockdep_recursion);  }  static inline void lockdep_unlock(void)  { +	DEBUG_LOCKS_WARN_ON(!irqs_disabled()); +  	if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current))  		return; -	__this_cpu_dec(lockdep_recursion);  	__owner = NULL;  	arch_spin_unlock(&__lock); +	__this_cpu_dec(lockdep_recursion);  }  static inline bool lockdep_assert_locked(void) @@ -2765,7 +2767,9 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,   * (Note that this has to be done separately, because the graph cannot   * detect such classes of deadlocks.)   * - * Returns: 0 on deadlock detected, 1 on OK, 2 on recursive read + * Returns: 0 on deadlock detected, 1 on OK, 2 if another lock with the same + * lock class is held but nest_lock is also held, i.e. we rely on the + * nest_lock to avoid the deadlock.   */  static int  check_deadlock(struct task_struct *curr, struct held_lock *next) @@ -2788,7 +2792,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next)  		 * lock class (i.e. read_lock(lock)+read_lock(lock)):  		 */  		if ((next->read == 2) && prev->read) -			return 2; +			continue;  		/*  		 * We're holding the nest_lock, which serializes this lock's @@ -3593,15 +3597,12 @@ static int validate_chain(struct task_struct *curr,  		if (!ret)  			return 0;  		/* -		 * Mark recursive read, as we jump over it when -		 * building dependencies (just like we jump over -		 * trylock entries): -		 */ -		if (ret == 2) -			hlock->read = 2; -		/*  		 * Add dependency only if this lock is not the head -		 * of the chain, and if it's not a secondary read-lock: +		 * of the chain, and if the new lock introduces no more +		 * lock dependency (because we already hold a lock with the +		 * same lock class) nor deadlock (because the nest_lock +		 * serializes nesting locks), see the comments for +		 * check_deadlock().  		 */  		if (!chain_head && ret != 2) {  			if (!check_prevs_add(curr, hlock))  |