Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Nov 2017 20:38:26 +0000 (12:38 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Nov 2017 20:38:26 +0000 (12:38 -0800)
Pull core locking updates from Ingo Molnar:
 "The main changes in this cycle are:

   - Another attempt at enabling cross-release lockdep dependency
     tracking (automatically part of CONFIG_PROVE_LOCKING=y), this time
     with better performance and fewer false positives. (Byungchul Park)

   - Introduce lockdep_assert_irqs_enabled()/disabled() and convert
     open-coded equivalents to lockdep variants. (Frederic Weisbecker)

   - Add down_read_killable() and use it in the VFS's iterate_dir()
     method. (Kirill Tkhai)

   - Convert remaining uses of ACCESS_ONCE() to
     READ_ONCE()/WRITE_ONCE(). Most of the conversion was Coccinelle
     driven. (Mark Rutland, Paul E. McKenney)

   - Get rid of lockless_dereference(), by strengthening Alpha atomics,
     strengthening READ_ONCE() with smp_read_barrier_depends() and thus
     being able to convert users of lockless_dereference() to
     READ_ONCE(). (Will Deacon)

   - Various micro-optimizations:

        - better PV qspinlocks (Waiman Long),
        - better x86 barriers (Michael S. Tsirkin)
        - better x86 refcounts (Kees Cook)

   - ... plus other fixes and enhancements. (Borislav Petkov, Juergen
     Gross, Miguel Bernal Marin)"

* 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits)
  locking/x86: Use LOCK ADD for smp_mb() instead of MFENCE
  rcu: Use lockdep to assert IRQs are disabled/enabled
  netpoll: Use lockdep to assert IRQs are disabled/enabled
  timers/posix-cpu-timers: Use lockdep to assert IRQs are disabled/enabled
  sched/clock, sched/cputime: Use lockdep to assert IRQs are disabled/enabled
  irq_work: Use lockdep to assert IRQs are disabled/enabled
  irq/timings: Use lockdep to assert IRQs are disabled/enabled
  perf/core: Use lockdep to assert IRQs are disabled/enabled
  x86: Use lockdep to assert IRQs are disabled/enabled
  smp/core: Use lockdep to assert IRQs are disabled/enabled
  timers/hrtimer: Use lockdep to assert IRQs are disabled/enabled
  timers/nohz: Use lockdep to assert IRQs are disabled/enabled
  workqueue: Use lockdep to assert IRQs are disabled/enabled
  irq/softirqs: Use lockdep to assert IRQs are disabled/enabled
  locking/lockdep: Add IRQs disabled/enabled assertion APIs: lockdep_assert_irqs_enabled()/disabled()
  locking/pvqspinlock: Implement hybrid PV queued/unfair locks
  locking/rwlocks: Fix comments
  x86/paravirt: Set up the virt_spin_lock_key after static keys get initialized
  block, locking/lockdep: Assign a lock_class per gendisk used for wait_for_completion()
  workqueue: Remove now redundant lock acquisitions wrt. workqueue flushes
  ...

1  2 
Documentation/admin-guide/kernel-parameters.txt
Documentation/memory-barriers.txt
arch/s390/include/asm/spinlock.h
arch/s390/lib/spinlock.c
arch/x86/kernel/smpboot.c
drivers/net/bonding/bond_main.c
kernel/irq_work.c
kernel/rcu/tree.c
kernel/rcu/tree_plugin.h
net/ipv4/tcp_input.c

Simple merge
index 31f95a636aed8361e94b360ae16dfde6b55b69fa,d97175e16d9b48aaca6857ad05433fcfc0edab6f..0a29588aa00b64e21ffba5b31d77be94982f47a0
@@@ -37,7 -36,7 +37,8 @@@ bool arch_vcpu_is_preempted(int cpu)
   * (the type definitions are in asm/spinlock_types.h)
   */
  
 -void arch_lock_relax(int cpu);
 +void arch_spin_relax(arch_spinlock_t *lock);
++#define arch_spin_relax       arch_spin_relax
  
  void arch_spin_lock_wait(arch_spinlock_t *);
  int arch_spin_trylock_retry(arch_spinlock_t *);
@@@ -74,8 -80,9 +75,9 @@@ static inline void arch_spin_lock_flags
                                        unsigned long flags)
  {
        if (!arch_spin_trylock_once(lp))
 -              arch_spin_lock_wait_flags(lp, flags);
 +              arch_spin_lock_wait(lp);
  }
+ #define arch_spin_lock_flags  arch_spin_lock_flags
  
  static inline int arch_spin_trylock(arch_spinlock_t *lp)
  {
@@@ -105,25 -113,58 +107,11 @@@ static inline void arch_spin_unlock(arc
   * read-locks.
   */
  
- /**
-  * read_can_lock - would read_trylock() succeed?
-  * @lock: the rwlock in question.
-  */
- #define arch_read_can_lock(x) (((x)->cnts & 0xffff0000) == 0)
 -extern int _raw_read_trylock_retry(arch_rwlock_t *lp);
 -extern int _raw_write_trylock_retry(arch_rwlock_t *lp);
--
- /**
-  * write_can_lock - would write_trylock() succeed?
-  * @lock: the rwlock in question.
-  */
- #define arch_write_can_lock(x) ((x)->cnts == 0)
 -static inline int arch_read_trylock_once(arch_rwlock_t *rw)
 -{
 -      int old = READ_ONCE(rw->lock);
 -      return likely(old >= 0 &&
 -                    __atomic_cmpxchg_bool(&rw->lock, old, old + 1));
 -}
--
- #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
- #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 -static inline int arch_write_trylock_once(arch_rwlock_t *rw)
 -{
 -      int old = READ_ONCE(rw->lock);
 -      return likely(old == 0 &&
 -                    __atomic_cmpxchg_bool(&rw->lock, 0, 0x80000000));
 -}
 -
 -#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
 +#define arch_read_relax(rw) barrier()
 +#define arch_write_relax(rw) barrier()
  
 -#define __RAW_OP_OR   "lao"
 -#define __RAW_OP_AND  "lan"
 -#define __RAW_OP_ADD  "laa"
 -
 -#define __RAW_LOCK(ptr, op_val, op_string)            \
 -({                                                    \
 -      int old_val;                                    \
 -                                                      \
 -      typecheck(int *, ptr);                          \
 -      asm volatile(                                   \
 -              op_string "     %0,%2,%1\n"             \
 -              "bcr    14,0\n"                         \
 -              : "=d" (old_val), "+Q" (*ptr)           \
 -              : "d" (op_val)                          \
 -              : "cc", "memory");                      \
 -      old_val;                                        \
 -})
 -
 -#define __RAW_UNLOCK(ptr, op_val, op_string)          \
 -({                                                    \
 -      int old_val;                                    \
 -                                                      \
 -      typecheck(int *, ptr);                          \
 -      asm volatile(                                   \
 -              op_string "     %0,%2,%1\n"             \
 -              : "=d" (old_val), "+Q" (*ptr)           \
 -              : "d" (op_val)                          \
 -              : "cc", "memory");                      \
 -      old_val;                                        \
 -})
 -
 -extern void _raw_read_lock_wait(arch_rwlock_t *lp);
 -extern void _raw_write_lock_wait(arch_rwlock_t *lp, int prev);
 +void arch_read_lock_wait(arch_rwlock_t *lp);
 +void arch_write_lock_wait(arch_rwlock_t *lp);
  
  static inline void arch_read_lock(arch_rwlock_t *rw)
  {
index 2a781cb6515ca1dd1cced00a99ef158b1cb5bf7b,2d0af866769566125a0e08cb70a495bb7f003961..84c0faeaf7ea7c6dab061e6cc4993fcf642cc140
@@@ -192,32 -83,28 +192,32 @@@ static inline void arch_spin_lock_queue
                if (count-- >= 0)
                        continue;
                count = spin_retry;
 -              /*
 -               * For multiple layers of hypervisors, e.g. z/VM + LPAR
 -               * yield the CPU unconditionally. For LPAR rely on the
 -               * sense running status.
 -               */
 -              if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner))
 -                      smp_yield_cpu(~owner);
 +              if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(owner - 1))
 +                      smp_yield_cpu(owner - 1);
        }
 +
 +      /* Pass lock_spin job to next CPU in the queue */
 +      if (node_id && tail_id != node_id) {
 +              /* Wait until the next CPU has set up the 'next' pointer */
 +              while ((next = READ_ONCE(node->next)) == NULL)
 +                      ;
 +              next->prev = NULL;
 +      }
 +
 + out:
 +      S390_lowcore.spinlock_index--;
  }
 -EXPORT_SYMBOL(arch_spin_lock_wait);
  
 -void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
 +static inline void arch_spin_lock_classic(arch_spinlock_t *lp)
  {
 -      int cpu = SPINLOCK_LOCKVAL;
 -      int owner, count;
 +      int lockval, old, new, owner, count;
  
 -      local_irq_restore(flags);
 +      lockval = SPINLOCK_LOCKVAL;     /* cpu + 1 */
  
        /* Pass the virtual CPU to the lock holder if it is not running */
-       owner = arch_spin_yield_target(ACCESS_ONCE(lp->lock), NULL);
 -      owner = arch_load_niai4(&lp->lock);
 -      if (owner && arch_vcpu_is_preempted(~owner))
 -              smp_yield_cpu(~owner);
++      owner = arch_spin_yield_target(READ_ONCE(lp->lock), NULL);
 +      if (owner && arch_vcpu_is_preempted(owner - 1))
 +              smp_yield_cpu(owner - 1);
  
        count = spin_retry;
        while (1) {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge