diff options
Diffstat (limited to 'kernel/locking')
| -rw-r--r-- | kernel/locking/Makefile | 1 | ||||
| -rw-r--r-- | kernel/locking/lockdep.c | 48 | ||||
| -rw-r--r-- | kernel/locking/lockdep_internals.h | 1 | ||||
| -rw-r--r-- | kernel/locking/lockdep_proc.c | 1 | ||||
| -rw-r--r-- | kernel/locking/mcs_spinlock.h | 1 | ||||
| -rw-r--r-- | kernel/locking/mutex-debug.h | 1 | ||||
| -rw-r--r-- | kernel/locking/mutex.h | 1 | ||||
| -rw-r--r-- | kernel/locking/osq_lock.c | 1 | ||||
| -rw-r--r-- | kernel/locking/qspinlock_paravirt.h | 1 | ||||
| -rw-r--r-- | kernel/locking/rtmutex-debug.c | 1 | ||||
| -rw-r--r-- | kernel/locking/rtmutex-debug.h | 1 | ||||
| -rw-r--r-- | kernel/locking/rtmutex.h | 1 | ||||
| -rw-r--r-- | kernel/locking/rtmutex_common.h | 1 | ||||
| -rw-r--r-- | kernel/locking/rwsem-spinlock.c | 1 | ||||
| -rw-r--r-- | kernel/locking/rwsem-xadd.c | 28 | ||||
| -rw-r--r-- | kernel/locking/rwsem.c | 1 | ||||
| -rw-r--r-- | kernel/locking/rwsem.h | 1 | ||||
| -rw-r--r-- | kernel/locking/spinlock.c | 1 | 
18 files changed, 64 insertions, 28 deletions
| diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 760158d9d98d..392c7f23af76 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  # Any varying coverage in these files is non-deterministic  # and is generally not a function of system call inputs.  KCOV_INSTRUMENT		:= n diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 44c8d0d17170..e36e652d996f 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,  	       struct held_lock *next, int distance, struct stack_trace *trace,  	       int (*save)(struct stack_trace *trace))  { +	struct lock_list *uninitialized_var(target_entry);  	struct lock_list *entry; -	int ret;  	struct lock_list this; -	struct lock_list *uninitialized_var(target_entry); +	int ret;  	/*  	 * Prove that the new <prev> -> <next> dependency would not @@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,  	this.class = hlock_class(next);  	this.parent = NULL;  	ret = check_noncircular(&this, hlock_class(prev), &target_entry); -	if (unlikely(!ret)) +	if (unlikely(!ret)) { +		if (!trace->entries) { +			/* +			 * If @save fails here, the printing might trigger +			 * a WARN but because of the !nr_entries it should +			 * not do bad things. +			 */ +			save(trace); +		}  		return print_circular_bug(&this, target_entry, next, prev, trace); +	}  	else if (unlikely(ret < 0))  		return print_bfs_bug(ret); @@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,  		return print_bfs_bug(ret); -	if (save && !save(trace)) +	if (!trace->entries && !save(trace))  		return 0;  	/* @@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,  	if (!ret)  		return 0; -	/* -	 * Debugging printouts: -	 */ -	if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) { -		graph_unlock(); -		printk("\n new dependency: "); -		print_lock_name(hlock_class(prev)); -		printk(KERN_CONT " => "); -		print_lock_name(hlock_class(next)); -		printk(KERN_CONT "\n"); -		dump_stack(); -		if (!graph_lock()) -			return 0; -	}  	return 2;  } @@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)  {  	int depth = curr->lockdep_depth;  	struct held_lock *hlock; -	struct stack_trace trace; -	int (*save)(struct stack_trace *trace) = save_trace; +	struct stack_trace trace = { +		.nr_entries = 0, +		.max_entries = 0, +		.entries = NULL, +		.skip = 0, +	};  	/*  	 * Debugging checks. @@ -2018,18 +2017,11 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)  			 */  			if (hlock->read != 2 && hlock->check) {  				int ret = check_prev_add(curr, hlock, next, -							 distance, &trace, save); +							 distance, &trace, save_trace);  				if (!ret)  					return 0;  				/* -				 * Stop saving stack_trace if save_trace() was -				 * called at least once: -				 */ -				if (save && ret == 2) -					save = NULL; - -				/*  				 * Stop after the first non-trylock entry,  				 * as non-trylock entries have added their  				 * own direct dependencies already, so this diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h index 1da4669d57a7..d459d624ba2a 100644 --- a/kernel/locking/lockdep_internals.h +++ b/kernel/locking/lockdep_internals.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * kernel/lockdep_internals.h   * diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 68d9e267ccd4..ad69bbc9bd28 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * kernel/lockdep_proc.c   * diff --git a/kernel/locking/mcs_spinlock.h b/kernel/locking/mcs_spinlock.h index 6a385aabcce7..f046b7ce9dd6 100644 --- a/kernel/locking/mcs_spinlock.h +++ b/kernel/locking/mcs_spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * MCS lock defines   * diff --git a/kernel/locking/mutex-debug.h b/kernel/locking/mutex-debug.h index 4174417d5309..1edd3f45a4ec 100644 --- a/kernel/locking/mutex-debug.h +++ b/kernel/locking/mutex-debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * Mutexes: blocking mutual exclusion locks   * diff --git a/kernel/locking/mutex.h b/kernel/locking/mutex.h index 6ebc1902f779..1c2287d3fa71 100644 --- a/kernel/locking/mutex.h +++ b/kernel/locking/mutex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * Mutexes: blocking mutual exclusion locks   * diff --git a/kernel/locking/osq_lock.c b/kernel/locking/osq_lock.c index a74ee6abd039..6ef600aa0f47 100644 --- a/kernel/locking/osq_lock.c +++ b/kernel/locking/osq_lock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <linux/percpu.h>  #include <linux/sched.h>  #include <linux/osq_lock.h> diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index 43555681c40b..15b6a39366c6 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef _GEN_PV_LOCK_SLOWPATH  #error "do not include this file"  #endif diff --git a/kernel/locking/rtmutex-debug.c b/kernel/locking/rtmutex-debug.c index f4a74e78d467..fd4fe1f5b458 100644 --- a/kernel/locking/rtmutex-debug.c +++ b/kernel/locking/rtmutex-debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * RT-Mutexes: blocking mutual exclusion locks with PI support   * diff --git a/kernel/locking/rtmutex-debug.h b/kernel/locking/rtmutex-debug.h index 5078c6ddf4a5..fc549713bba3 100644 --- a/kernel/locking/rtmutex-debug.h +++ b/kernel/locking/rtmutex-debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * RT-Mutexes: blocking mutual exclusion locks with PI support   * diff --git a/kernel/locking/rtmutex.h b/kernel/locking/rtmutex.h index 5c253caffe91..732f96abf462 100644 --- a/kernel/locking/rtmutex.h +++ b/kernel/locking/rtmutex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * RT-Mutexes: blocking mutual exclusion locks with PI support   * diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h index 7453be0485a5..124e98ca0b17 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * RT Mutexes: blocking mutual exclusion locks with PI support   * diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 0848634c5512..a7ffb2a96ede 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /* rwsem-spinlock.c: R/W semaphores: contention handling functions for   * generic spinlock implementation   * diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 02f660666ab8..e795908f3607 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /* rwsem.c: R/W semaphores: contention handling functions   *   * Written by David Howells ([email protected]). @@ -613,6 +614,33 @@ struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem)  	DEFINE_WAKE_Q(wake_q);  	/* +	* __rwsem_down_write_failed_common(sem) +	*   rwsem_optimistic_spin(sem) +	*     osq_unlock(sem->osq) +	*   ... +	*   atomic_long_add_return(&sem->count) +	* +	*      - VS - +	* +	*              __up_write() +	*                if (atomic_long_sub_return_release(&sem->count) < 0) +	*                  rwsem_wake(sem) +	*                    osq_is_locked(&sem->osq) +	* +	* And __up_write() must observe !osq_is_locked() when it observes the +	* atomic_long_add_return() in order to not miss a wakeup. +	* +	* This boils down to: +	* +	* [S.rel] X = 1                [RmW] r0 = (Y += 0) +	*         MB                         RMB +	* [RmW]   Y += 1               [L]   r1 = X +	* +	* exists (r0=1 /\ r1=0) +	*/ +	smp_rmb(); + +	/*  	 * If a spinner is present, it is not necessary to do the wakeup.  	 * Try to do wakeup only if the trylock succeeds to minimize  	 * spinlock contention which may introduce too much delay in the diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 4d48b1c4870d..a6c76a4832b4 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /* kernel/rwsem.c: R/W semaphores, public implementation   *   * Written by David Howells ([email protected]). diff --git a/kernel/locking/rwsem.h b/kernel/locking/rwsem.h index a699f4048ba1..a883b8f1fdc6 100644 --- a/kernel/locking/rwsem.h +++ b/kernel/locking/rwsem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * The owner field of the rw_semaphore structure will be set to   * RWSEM_READ_OWNED when a reader grabs the lock. A writer will clear diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c index 4b082b5cac9e..6e40fdfba326 100644 --- a/kernel/locking/spinlock.c +++ b/kernel/locking/spinlock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * Copyright (2004) Linus Torvalds   * |