Skip to content

Commit

Permalink
Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/tip

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
  ...
  • Loading branch information
torvalds committed Nov 13, 2017
2 parents 6098850 + 450cbdd commit 8e9a2db
Show file tree
Hide file tree
Showing 307 changed files with 1,252 additions and 1,672 deletions.
3 changes: 3 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,9 @@
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.

crossrelease_fullstack
[KNL] Allow to record full stack trace in cross-release

cryptomgr.notests
[KNL] Disable crypto self-tests

Expand Down
6 changes: 3 additions & 3 deletions Documentation/filesystems/path-lookup.md
Original file line number Diff line number Diff line change
Expand Up @@ -826,9 +826,9 @@ If the filesystem may need to revalidate dcache entries, then
*is* passed the dentry but does not have access to the `inode` or the
`seq` number from the `nameidata`, so it needs to be extra careful
when accessing fields in the dentry. This "extra care" typically
involves using `ACCESS_ONCE()` or the newer [`READ_ONCE()`] to access
fields, and verifying the result is not NULL before using it. This
pattern can be see in `nfs_lookup_revalidate()`.
involves using [`READ_ONCE()`] to access fields, and verifying the
result is not NULL before using it. This pattern can be seen in
`nfs_lookup_revalidate()`.

A pair of patterns
------------------
Expand Down
12 changes: 0 additions & 12 deletions Documentation/memory-barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1880,18 +1880,6 @@ There are some more advanced barrier functions:
See Documentation/atomic_{t,bitops}.txt for more information.


(*) lockless_dereference();

This can be thought of as a pointer-fetch wrapper around the
smp_read_barrier_depends() data-dependency barrier.

This is also similar to rcu_dereference(), but in cases where
object lifetime is handled by some mechanism other than RCU, for
example, when the objects removed only when the system goes down.
In addition, lockless_dereference() is used in some data structures
that can be used both with and without RCU.


(*) dma_wmb();
(*) dma_rmb();

Expand Down
12 changes: 0 additions & 12 deletions Documentation/translations/ko_KR/memory-barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1858,18 +1858,6 @@ Mandatory 배리어들은 SMP 시스템에서도 UP 시스템에서도 SMP 효
참고하세요.


(*) lockless_dereference();

이 함수는 smp_read_barrier_depends() 데이터 의존성 배리어를 사용하는
포인터 읽어오기 래퍼(wrapper) 함수로 생각될 수 있습니다.

객체의 라이프타임이 RCU 외의 메커니즘으로 관리된다는 점을 제외하면
rcu_dereference() 와도 유사한데, 예를 들면 객체가 시스템이 꺼질 때에만
제거되는 경우 등입니다. 또한, lockless_dereference() 은 RCU 와 함께
사용될수도, RCU 없이 사용될 수도 있는 일부 데이터 구조에 사용되고
있습니다.


(*) dma_wmb();
(*) dma_rmb();

Expand Down
13 changes: 13 additions & 0 deletions arch/alpha/include/asm/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
* than regular operations.
*/

/*
* To ensure dependency ordering is preserved for the _relaxed and
* _release atomics, an smp_read_barrier_depends() is unconditionally
* inserted into the _relaxed variants, which are used to build the
* barriered versions. To avoid redundant back-to-back fences, we can
* define the _acquire and _fence versions explicitly.
*/
#define __atomic_op_acquire(op, args...) op##_relaxed(args)
#define __atomic_op_fence __atomic_op_release

#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
Expand Down Expand Up @@ -61,6 +70,7 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_read_barrier_depends(); \
return result; \
}

Expand All @@ -78,6 +88,7 @@ static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_read_barrier_depends(); \
return result; \
}

Expand Down Expand Up @@ -112,6 +123,7 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_read_barrier_depends(); \
return result; \
}

Expand All @@ -129,6 +141,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_read_barrier_depends(); \
return result; \
}

Expand Down
21 changes: 18 additions & 3 deletions arch/alpha/include/asm/rwsem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)

static inline void __down_read(struct rw_semaphore *sem)
static inline int ___down_read(struct rw_semaphore *sem)
{
long oldcount;
#ifndef CONFIG_SMP
Expand All @@ -42,10 +42,24 @@ static inline void __down_read(struct rw_semaphore *sem)
:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
:"Ir" (RWSEM_ACTIVE_READ_BIAS), "m" (sem->count) : "memory");
#endif
if (unlikely(oldcount < 0))
return (oldcount < 0);
}

static inline void __down_read(struct rw_semaphore *sem)
{
if (unlikely(___down_read(sem)))
rwsem_down_read_failed(sem);
}

static inline int __down_read_killable(struct rw_semaphore *sem)
{
if (unlikely(___down_read(sem)))
if (IS_ERR(rwsem_down_read_failed_killable(sem)))
return -EINTR;

return 0;
}

/*
* trylock for reading -- returns 1 if successful, 0 if contention
*/
Expand Down Expand Up @@ -95,9 +109,10 @@ static inline void __down_write(struct rw_semaphore *sem)

static inline int __down_write_killable(struct rw_semaphore *sem)
{
if (unlikely(___down_write(sem)))
if (unlikely(___down_write(sem))) {
if (IS_ERR(rwsem_down_write_failed_killable(sem)))
return -EINTR;
}

return 0;
}
Expand Down
14 changes: 0 additions & 14 deletions arch/alpha/include/asm/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* We make no fairness assumptions. They have a cost.
*/

#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
#define arch_spin_is_locked(x) ((x)->lock != 0)

static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
Expand Down Expand Up @@ -55,16 +54,6 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)

/***********************************************************/

static inline int arch_read_can_lock(arch_rwlock_t *lock)
{
return (lock->lock & 1) == 0;
}

static inline int arch_write_can_lock(arch_rwlock_t *lock)
{
return lock->lock == 0;
}

static inline void arch_read_lock(arch_rwlock_t *lock)
{
long regx;
Expand Down Expand Up @@ -171,7 +160,4 @@ static inline void arch_write_unlock(arch_rwlock_t * lock)
lock->lock = 0;
}

#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)

#endif /* _ALPHA_SPINLOCK_H */
11 changes: 0 additions & 11 deletions arch/arc/include/asm/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <asm/barrier.h>

#define arch_spin_is_locked(x) ((x)->slock != __ARCH_SPIN_LOCK_UNLOCKED__)
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)

#ifdef CONFIG_ARC_HAS_LLSC

Expand Down Expand Up @@ -410,14 +409,4 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)

#endif

#define arch_read_can_lock(x) ((x)->counter > 0)
#define arch_write_can_lock(x) ((x)->counter == __ARCH_RW_LOCK_UNLOCKED__)

#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)

#define arch_spin_relax(lock) cpu_relax()
#define arch_read_relax(lock) cpu_relax()
#define arch_write_relax(lock) cpu_relax()

#endif /* __ASM_SPINLOCK_H */
2 changes: 1 addition & 1 deletion arch/arc/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static void ipi_send_msg_one(int cpu, enum ipi_msg_type msg)
* and read back old value
*/
do {
new = old = ACCESS_ONCE(*ipi_data_ptr);
new = old = READ_ONCE(*ipi_data_ptr);
new |= 1U << msg;
} while (cmpxchg(ipi_data_ptr, old, new) != old);

Expand Down
3 changes: 1 addition & 2 deletions arch/arm/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ extern unsigned long profile_pc(struct pt_regs *regs);
/*
* kprobe-based event tracer support
*/
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/compiler.h>
#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))

extern int regs_query_register_offset(const char *name);
Expand Down
17 changes: 1 addition & 16 deletions arch/arm/include/asm/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ static inline void dsb_sev(void)
* memory.
*/

#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp;
Expand All @@ -74,7 +72,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)

while (lockval.tickets.next != lockval.tickets.owner) {
wfe();
lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);
lockval.tickets.owner = READ_ONCE(lock->tickets.owner);
}

smp_mb();
Expand Down Expand Up @@ -194,9 +192,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
dsb_sev();
}

/* write_can_lock - would write_trylock() succeed? */
#define arch_write_can_lock(x) (ACCESS_ONCE((x)->lock) == 0)

/*
* Read locks are a bit more hairy:
* - Exclusively load the lock value.
Expand Down Expand Up @@ -274,14 +269,4 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
}
}

/* read_can_lock - would read_trylock() succeed? */
#define arch_read_can_lock(x) (ACCESS_ONCE((x)->lock) < 0x80000000)

#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)

#define arch_spin_relax(lock) cpu_relax()
#define arch_read_relax(lock) cpu_relax()
#define arch_write_relax(lock) cpu_relax()

#endif /* __ASM_SPINLOCK_H */
2 changes: 1 addition & 1 deletion arch/arm/mach-tegra/cpuidle-tegra20.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
bool entered_lp2 = false;

if (tegra_pending_sgi())
ACCESS_ONCE(abort_flag) = true;
WRITE_ONCE(abort_flag, true);

cpuidle_coupled_parallel_barrier(dev, &abort_barrier);

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/vdso/vgettimeofday.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static notrace u32 __vdso_read_begin(const struct vdso_data *vdata)
{
u32 seq;
repeat:
seq = ACCESS_ONCE(vdata->seq_count);
seq = READ_ONCE(vdata->seq_count);
if (seq & 1) {
cpu_relax();
goto repeat;
Expand Down
17 changes: 17 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,24 @@ config ARM64
select ARCH_HAS_STRICT_MODULE_RWX
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAVE_NMI_SAFE_CMPXCHG if ACPI_APEI_SEA
select ARCH_INLINE_READ_LOCK if !PREEMPT
select ARCH_INLINE_READ_LOCK_BH if !PREEMPT
select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPT
select ARCH_INLINE_READ_LOCK_IRQSAVE if !PREEMPT
select ARCH_INLINE_READ_UNLOCK if !PREEMPT
select ARCH_INLINE_READ_UNLOCK_BH if !PREEMPT
select ARCH_INLINE_READ_UNLOCK_IRQ if !PREEMPT
select ARCH_INLINE_READ_UNLOCK_IRQRESTORE if !PREEMPT
select ARCH_INLINE_WRITE_LOCK if !PREEMPT
select ARCH_INLINE_WRITE_LOCK_BH if !PREEMPT
select ARCH_INLINE_WRITE_LOCK_IRQ if !PREEMPT
select ARCH_INLINE_WRITE_LOCK_IRQSAVE if !PREEMPT
select ARCH_INLINE_WRITE_UNLOCK if !PREEMPT
select ARCH_INLINE_WRITE_UNLOCK_BH if !PREEMPT
select ARCH_INLINE_WRITE_UNLOCK_IRQ if !PREEMPT
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE if !PREEMPT
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_NUMA_BALANCING
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ generic-y += mcs_spinlock.h
generic-y += mm-arch-hooks.h
generic-y += msi.h
generic-y += preempt.h
generic-y += qrwlock.h
generic-y += rwsem.h
generic-y += segment.h
generic-y += serial.h
Expand Down
Loading

0 comments on commit 8e9a2db

Please sign in to comment.