locking changes for v4.7
Subsystems (6)
Ingo Molnar
maintainerLinus,
Please pull the latest locking-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking-core-for-linus
# HEAD: a1cc5bcfcfca0b99f009b117785142dbdc3b87a3 locking/atomics: Flip atomic_fetch_or() arguments
The main changes in this cycle were:
- pvqspinlock statistics fixes (Davidlohr Bueso)
- flip atomic_fetch_or() arguments (Peter Zijlstra)
- locktorture simplification (Paul E. McKenney)
- documentation updates (SeongJae Park, David Howells, Davidlohr Bueso, Paul E. McKenney, Peter Zijlstra, Will Deacon)
- various fixes
Thanks,
Ingo
------------------>
David Howells (1):
locking/Documentation: State purpose of memory-barriers.txt
Davidlohr Bueso (5):
locking/Documentation: Mention smp_cond_acquire() locking/locktorture: Fix deboosting NULL pointer dereference locking/locktorture: Fix NULL pointer dereference for cleanup paths locking/pvqspinlock: Avoid double resetting of stats locking/pvqspinlock: Robustify init_qspinlock_stat()
Denys Vlasenko (1):
locking/lockdep: Deinline register_lock_class(), save 2328 bytes
Eric Engestrom (1):
locking/Documentation/lockdep: Fix spelling mistakes
Paul E. McKenney (2):
locking/Documentation: Clarify relationship of barrier() to control dependencies lcoking/locktorture: Simplify the torture_runnable computation
Peter Zijlstra (2):
locking/Documentation: Add disclaimer locking/atomics: Flip atomic_fetch_or() arguments
SeongJae Park (4):
locking/Documentation: Fix missed s/lock/acquire renames locking/Documentation: Add missed subsection in TOC locking/Documentation: Fix formatting inconsistencies locking/Documentation: Insert white spaces consistently
Will Deacon (1):
locking/Documentation: Clarify that ACQUIRE applies to loads, RELEASE applies to stores
Documentation/locking/lockdep-design.txt | 4 +- Documentation/memory-barriers.txt | 117 +++++++++++++++++++++---------- include/linux/atomic.h | 4 +- kernel/locking/lockdep.c | 2 +- kernel/locking/locktorture.c | 25 ++++--- kernel/locking/qspinlock_stat.h | 24 ++++--- kernel/time/tick-sched.c | 4 +- 7 files changed, 117 insertions(+), 63 deletions(-)
Documentation/locking/lockdep-design.txt +2 -2
@@ -97,7 +97,7 @@ Furthermore, the following usage based lock dependencies are not allowed <hardirq-safe> -> <hardirq-unsafe> <softirq-safe> -> <softirq-unsafe> -The first rule comes from the fact the a hardirq-safe lock could be +The first rule comes from the fact that a hardirq-safe lock could be taken by a hardirq context, interrupting a hardirq-unsafe lock - and thus could result in a lock inversion deadlock. Likewise, a softirq-safe lock could be taken by an softirq context, interrupting a softirq-unsafe
@@ -220,7 +220,7 @@ calculated, which hash is unique for every lock chain. The hash value, when the chain is validated for the first time, is then put into a hash table, which hash-table can be checked in a lockfree manner. If the locking chain occurs again later on, the hash table tells us that we -dont have to validate the chain again. +don't have to validate the chain again. Troubleshooting: ----------------
Documentation/memory-barriers.txt +80 -37
279 lines not on this page · raw message
include/linux/atomic.h +2 -2
@@ -560,11 +560,11 @@ static inline int atomic_dec_if_positive(atomic_t *v)/** * atomic_fetch_or - perform *p |= mask and return old value of *p -* @p: pointer to atomic_t * @mask: mask to OR on the atomic_t +* @p: pointer to atomic_t */ #ifndef atomic_fetch_or -static inline int atomic_fetch_or (atomic_t *p,int mask) +static inline int atomic_fetch_or (int mask,atomic_t *p) {int old, val =atomic_read (p);
kernel/locking/lockdep.c +1 -1
@@ -708,7 +708,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)* yet. Otherwise we look it up. We cache the result in the lock object * itself, so actual lookup of the hash should be once per lock object. */ -static inline struct lock_class * +static struct lock_class *register_lock_class (struct lockdep_map *lock,unsigned int subclass,int force) {struct lockdep_subclass_key *key;
kernel/locking/locktorture.c +16 -9
@@ -75,12 +75,7 @@ struct lock_stress_stats {long n_lock_acquired; }; -#if defined(MODULE ) -#define LOCKTORTURE_RUNNABLE_INIT 1 -#else -#define LOCKTORTURE_RUNNABLE_INIT 0 -#endif -int torture_runnable =LOCKTORTURE_RUNNABLE_INIT ; +int torture_runnable =IS_ENABLED (MODULE );module_param (torture_runnable, int,0444 );MODULE_PARM_DESC (torture_runnable,"Start locktorture at module init" );
@@ -394,12 +389,12 @@ static void torture_rtmutex_boost(struct torture_random_state *trsp)if (!rt_task (current)) {/* -* (1) Boost priority once every ~50k operations. When the +* Boost priority once every ~50k operations. When the * task tries to take the lock, the rtmutex it will account * for the new priority, and do any corresponding pi-dance. */ -if (!(torture_random (trsp) % - (cxt.nrealwriters_stress * factor))) { +if (trsp && !(torture_random (trsp) % + (cxt.nrealwriters_stress * factor))) { policy =SCHED_FIFO ; param.sched_priority =MAX_RT_PRIO -1 ; }else /* common case, do nothing */
@@ -748,6 +743,15 @@ static void lock_torture_cleanup(void)if (torture_cleanup_begin ())return ; +/* +* Indicates early cleanup, meaning that the test has not run, +* such as when passing bogus args when loading the module. As +* such, only perform the underlying torture-specific cleanups, +* and avoid anything related to locktorture. +*/ +if (!cxt.lwsa) + goto end; +if (writer_tasks) {for (i =0 ; i < cxt.nrealwriters_stress; i++) torture_stop_kthread(lock_torture_writer,
@@ -776,6 +780,7 @@ static void lock_torture_cleanup(void)else lock_torture_print_module_parms (cxt.cur_ops,"End of test: SUCCESS" ); +end:torture_cleanup_end (); }
@@ -870,6 +875,7 @@ static int __init lock_torture_init(void)VERBOSE_TOROUT_STRING ("cxt.lrsa: Out of memory" ); firsterr = -ENOMEM ;kfree (cxt.lwsa); + cxt.lwsa =NULL ; goto unwind; }
@@ -878,6 +884,7 @@ static int __init lock_torture_init(void) cxt.lrsa[i].n_lock_acquired =0 ; } } +lock_torture_print_module_parms (cxt.cur_ops,"Start of test" );/* Prepare torture context. */
kernel/locking/qspinlock_stat.h +14 -10
@@ -191,8 +191,6 @@ static ssize_t qstat_write(struct file *file, const char __user *user_buf,for (i =0 ; i < qstat_num; i++)WRITE_ONCE (ptr[i],0 ); -for (i =0 ; i < qstat_num; i++) -WRITE_ONCE (ptr[i],0 ); }return count; }
@@ -214,10 +212,8 @@ static int __init init_qspinlock_stat(void)struct dentry *d_qstat =debugfs_create_dir ("qlockstat" ,NULL );int i; -if (!d_qstat) { -pr_warn ("Could not create 'qlockstat' debugfs directory\n" ); -return 0 ; - } +if (!d_qstat) + goto out;/* * Create the debugfs files
@@ -227,12 +223,20 @@ static int __init init_qspinlock_stat(void)* performance. */ for (i =0 ; i < qstat_num; i++) -debugfs_create_file (qstat_names[i],0400 , d_qstat, - (void *)(long )i, &fops_qstat); +if (!debugfs_create_file (qstat_names[i],0400 , d_qstat, + (void *)(long )i, &fops_qstat)) + goto fail_undo; + +if (!debugfs_create_file (qstat_names[qstat_reset_cnts],0200 , d_qstat, + (void *)(long )qstat_reset_cnts, &fops_qstat)) + goto fail_undo; -debugfs_create_file (qstat_names[qstat_reset_cnts],0200 , d_qstat, - (void *)(long )qstat_reset_cnts, &fops_qstat);return 0 ; +fail_undo: +debugfs_remove_recursive (d_qstat); +out: +pr_warn ("Could not create 'qlockstat' debugfs entries\n" ); +return -ENOMEM ; }fs_initcall (init_qspinlock_stat);
kernel/time/tick-sched.c +2 -2
@@ -262,7 +262,7 @@ static void tick_nohz_dep_set_all(atomic_t *dep, {int prev; - prev =atomic_fetch_or (dep,BIT (bit)); + prev =atomic_fetch_or (BIT (bit), dep);if (!prev)tick_nohz_full_kick_all (); }
@@ -292,7 +292,7 @@ void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) ts =per_cpu_ptr (&tick_cpu_sched, cpu); - prev =atomic_fetch_or (&ts->tick_dep_mask,BIT (bit)); + prev =atomic_fetch_or (BIT (bit), &ts->tick_dep_mask);if (!prev) {preempt_disable ();/* Perf needs local kick that is NMI safe */