Skip to content

Commit

Permalink
Merge tag 'locking-urgent-2020-08-10' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/tip

Pull locking updates from Thomas Gleixner:
 "A set of locking fixes and updates:

   - Untangle the header spaghetti which causes build failures in
     various situations caused by the lockdep additions to seqcount to
     validate that the write side critical sections are non-preemptible.

   - The seqcount associated lock debug addons which were blocked by the
     above fallout.

     seqcount writers contrary to seqlock writers must be externally
     serialized, which usually happens via locking - except for strict
     per CPU seqcounts. As the lock is not part of the seqcount, lockdep
     cannot validate that the lock is held.

     This new debug mechanism adds the concept of associated locks.
     sequence count has now lock type variants and corresponding
     initializers which take a pointer to the associated lock used for
     writer serialization. If lockdep is enabled the pointer is stored
     and write_seqcount_begin() has a lockdep assertion to validate that
     the lock is held.

     Aside of the type and the initializer no other code changes are
     required at the seqcount usage sites. The rest of the seqcount API
     is unchanged and determines the type at compile time with the help
     of _Generic which is possible now that the minimal GCC version has
     been moved up.

     Adding this lockdep coverage unearthed a handful of seqcount bugs
     which have been addressed already independent of this.

     While generally useful this comes with a Trojan Horse twist: On RT
     kernels the write side critical section can become preemtible if
     the writers are serialized by an associated lock, which leads to
     the well known reader preempts writer livelock. RT prevents this by
     storing the associated lock pointer independent of lockdep in the
     seqcount and changing the reader side to block on the lock when a
     reader detects that a writer is in the write side critical section.

   - Conversion of seqcount usage sites to associated types and
     initializers"

* tag 'locking-urgent-2020-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
  locking/seqlock, headers: Untangle the spaghetti monster
  locking, arch/ia64: Reduce <asm/smp.h> header dependencies by moving XTP bits into the new <asm/xtp.h> header
  x86/headers: Remove APIC headers from <asm/smp.h>
  seqcount: More consistent seqprop names
  seqcount: Compress SEQCNT_LOCKNAME_ZERO()
  seqlock: Fold seqcount_LOCKNAME_init() definition
  seqlock: Fold seqcount_LOCKNAME_t definition
  seqlock: s/__SEQ_LOCKDEP/__SEQ_LOCK/g
  hrtimer: Use sequence counter with associated raw spinlock
  kvm/eventfd: Use sequence counter with associated spinlock
  userfaultfd: Use sequence counter with associated spinlock
  NFSv4: Use sequence counter with associated spinlock
  iocost: Use sequence counter with associated spinlock
  raid5: Use sequence counter with associated spinlock
  vfs: Use sequence counter with associated spinlock
  timekeeping: Use sequence counter with associated raw spinlock
  xfrm: policy: Use sequence counters with associated lock
  netfilter: nft_set_rbtree: Use sequence counter with associated rwlock
  netfilter: conntrack: Use sequence counter with associated spinlock
  sched: tasks: Use sequence counter with associated spinlock
  ...
  • Loading branch information
torvalds committed Aug 11, 2020
2 parents 086ba2e + 0cd39f4 commit 97d052e
Show file tree
Hide file tree
Showing 78 changed files with 501 additions and 203 deletions.
52 changes: 52 additions & 0 deletions Documentation/locking/seqlock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,58 @@ Read path::
} while (read_seqcount_retry(&foo_seqcount, seq));


.. _seqcount_locktype_t:

Sequence counters with associated locks (``seqcount_LOCKTYPE_t``)
-----------------------------------------------------------------

As discussed at :ref:`seqcount_t`, sequence count write side critical
sections must be serialized and non-preemptible. This variant of
sequence counters associate the lock used for writer serialization at
initialization time, which enables lockdep to validate that the write
side critical sections are properly serialized.

This lock association is a NOOP if lockdep is disabled and has neither
storage nor runtime overhead. If lockdep is enabled, the lock pointer is
stored in struct seqcount and lockdep's "lock is held" assertions are
injected at the beginning of the write side critical section to validate
that it is properly protected.

For lock types which do not implicitly disable preemption, preemption
protection is enforced in the write side function.

The following sequence counters with associated locks are defined:

- ``seqcount_spinlock_t``
- ``seqcount_raw_spinlock_t``
- ``seqcount_rwlock_t``
- ``seqcount_mutex_t``
- ``seqcount_ww_mutex_t``

The plain seqcount read and write APIs branch out to the specific
seqcount_LOCKTYPE_t implementation at compile-time. This avoids kernel
API explosion per each new seqcount LOCKTYPE.

Initialization (replace "LOCKTYPE" with one of the supported locks)::

/* dynamic */
seqcount_LOCKTYPE_t foo_seqcount;
seqcount_LOCKTYPE_init(&foo_seqcount, &lock);

/* static */
static seqcount_LOCKTYPE_t foo_seqcount =
SEQCNT_LOCKTYPE_ZERO(foo_seqcount, &lock);

/* C99 struct init */
struct {
.seq = SEQCNT_LOCKTYPE_ZERO(foo.seq, &lock),
} foo;

Write path: same as in :ref:`seqcount_t`, while running from a context
with the associated LOCKTYPE lock acquired.

Read path: same as in :ref:`seqcount_t`.

.. _seqlock_t:

Sequential locks (``seqlock_t``)
Expand Down
35 changes: 0 additions & 35 deletions arch/ia64/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <linux/bitops.h>
#include <linux/irqreturn.h>

#include <asm/io.h>
#include <asm/param.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
Expand All @@ -44,11 +43,6 @@ ia64_get_lid (void)

#ifdef CONFIG_SMP

#define XTP_OFFSET 0x1e0008

#define SMP_IRQ_REDIRECTION (1 << 0)
#define SMP_IPI_REDIRECTION (1 << 1)

#define raw_smp_processor_id() (current_thread_info()->cpu)

extern struct smp_boot_data {
Expand All @@ -62,7 +56,6 @@ extern cpumask_t cpu_core_map[NR_CPUS];
DECLARE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
extern int smp_num_siblings;
extern void __iomem *ipi_base_addr;
extern unsigned char smp_int_redirect;

extern volatile int ia64_cpu_to_sapicid[];
#define cpu_physical_id(i) ia64_cpu_to_sapicid[i]
Expand All @@ -84,34 +77,6 @@ cpu_logical_id (int cpuid)
return i;
}

/*
* XTP control functions:
* min_xtp : route all interrupts to this CPU
* normal_xtp: nominal XTP value
* max_xtp : never deliver interrupts to this CPU.
*/

static inline void
min_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x00, ipi_base_addr + XTP_OFFSET); /* XTP to min */
}

static inline void
normal_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x08, ipi_base_addr + XTP_OFFSET); /* XTP normal */
}

static inline void
max_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x0f, ipi_base_addr + XTP_OFFSET); /* Set XTP to max */
}

/* Upping and downing of CPUs */
extern int __cpu_disable (void);
extern void __cpu_die (unsigned int cpu);
Expand Down
46 changes: 46 additions & 0 deletions arch/ia64/include/asm/xtp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_IA64_XTP_H
#define _ASM_IA64_XTP_H

#include <asm/io.h>

#ifdef CONFIG_SMP

#define XTP_OFFSET 0x1e0008

#define SMP_IRQ_REDIRECTION (1 << 0)
#define SMP_IPI_REDIRECTION (1 << 1)

extern unsigned char smp_int_redirect;

/*
* XTP control functions:
* min_xtp : route all interrupts to this CPU
* normal_xtp: nominal XTP value
* max_xtp : never deliver interrupts to this CPU.
*/

static inline void
min_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x00, ipi_base_addr + XTP_OFFSET); /* XTP to min */
}

static inline void
normal_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x08, ipi_base_addr + XTP_OFFSET); /* XTP normal */
}

static inline void
max_xtp (void)
{
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
writeb(0x0f, ipi_base_addr + XTP_OFFSET); /* Set XTP to max */
}

#endif /* CONFIG_SMP */

#endif /* _ASM_IA64_XTP_Hy */
1 change: 1 addition & 0 deletions arch/ia64/kernel/iosapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
#include <asm/iosapic.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/xtp.h>

#undef DEBUG_INTERRUPT_ROUTING

Expand Down
1 change: 1 addition & 0 deletions arch/ia64/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/kernel_stat.h>

#include <asm/mca.h>
#include <asm/xtp.h>

/*
* 'what should we do if we get a hw irq event on an illegal vector'.
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <linux/uaccess.h>
#include <asm/unwind.h>
#include <asm/user.h>
#include <asm/xtp.h>

#include "entry.h"

Expand Down
1 change: 1 addition & 0 deletions arch/ia64/kernel/sal.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <asm/page.h>
#include <asm/sal.h>
#include <asm/pal.h>
#include <asm/xtp.h>

__cacheline_aligned DEFINE_SPINLOCK(sal_lock);
unsigned long sal_platform_features;
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include <asm/tlbflush.h>
#include <asm/unistd.h>
#include <asm/uv/uv.h>
#include <asm/xtp.h>

#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
# error "struct cpuinfo_ia64 too big!"
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <asm/tlbflush.h>
#include <asm/unistd.h>
#include <asm/mca.h>
#include <asm/xtp.h>

/*
* Note: alignment of 4 entries/cacheline was empirically determined
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/include/asm/timex.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef _ASMPARISC_TIMEX_H
#define _ASMPARISC_TIMEX_H

#include <asm/special_insns.h>

#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */

Expand Down
1 change: 1 addition & 0 deletions arch/sh/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/cache.h>
#include <asm/addrspace.h>
#include <asm/machvec.h>
#include <asm/page.h>
#include <linux/pgtable.h>
#include <asm-generic/iomap.h>

Expand Down
1 change: 1 addition & 0 deletions arch/sh/kernel/machvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/processor.h>

#define MV_NAME_SIZE 32

Expand Down
1 change: 1 addition & 0 deletions arch/sparc/include/asm/timer_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef _SPARC64_TIMER_H
#define _SPARC64_TIMER_H

#include <uapi/asm/asi.h>
#include <linux/types.h>
#include <linux/init.h>

Expand Down
3 changes: 2 additions & 1 deletion arch/sparc/include/asm/vvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#define _ASM_SPARC_VVAR_DATA_H

#include <asm/clocksource.h>
#include <linux/seqlock.h>
#include <asm/processor.h>
#include <asm/barrier.h>
#include <linux/time.h>
#include <linux/types.h>

Expand Down
1 change: 0 additions & 1 deletion arch/sparc/kernel/vdso.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* a different vsyscall implementation for Linux/IA32 and for the name.
*/

#include <linux/seqlock.h>
#include <linux/time.h>
#include <linux/timekeeper_internal.h>

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/fixmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@

#ifndef __ASSEMBLY__
#include <linux/kernel.h>
#include <asm/acpi.h>
#include <asm/apicdef.h>
#include <asm/page.h>
#include <asm/pgtable_types.h>
#ifdef CONFIG_X86_32
#include <linux/threads.h>
#include <asm/kmap_types.h>
Expand Down
10 changes: 0 additions & 10 deletions arch/x86/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,6 @@
#include <linux/cpumask.h>
#include <asm/percpu.h>

/*
* We need the APIC definitions automatically as part of 'smp.h'
*/
#ifdef CONFIG_X86_LOCAL_APIC
# include <asm/mpspec.h>
# include <asm/apic.h>
# ifdef CONFIG_X86_IO_APIC
# include <asm/io_apic.h>
# endif
#endif
#include <asm/thread_info.h>
#include <asm/cpumask.h>

Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/tsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define _ASM_X86_TSC_H

#include <asm/processor.h>
#include <asm/cpufeature.h>

/*
* Standard way to access the cycle counter.
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <asm/proto.h>
#include <asm/traps.h>
#include <asm/apic.h>
#include <asm/acpi.h>
#include <asm/io_apic.h>
#include <asm/desc.h>
#include <asm/hpet.h>
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/apic_noop.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* like self-ipi, etc...
*/
#include <linux/cpumask.h>
#include <linux/thread_info.h>

#include <asm/apic.h>

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/bigsmp_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/smp.h>

#include <asm/apic.h>
#include <asm/io_apic.h>

#include "local.h"

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/hw_nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Bits copied from original nmi.c file
*
*/
#include <linux/thread_info.h>
#include <asm/apic.h>
#include <asm/nmi.h>

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/ipi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <linux/cpumask.h>
#include <linux/smp.h>
#include <asm/io_apic.h>

#include "local.h"

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/local.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <linux/jump_label.h>

#include <asm/irq_vectors.h>
#include <asm/apic.h>

/* APIC flat 64 */
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/probe_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/smp.h>

#include <asm/io_apic.h>
#include <asm/apic.h>
#include <asm/acpi.h>

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/probe_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
* James Cleverdon.
*/
#include <linux/thread_info.h>
#include <asm/apic.h>

#include "local.h"
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <asm/cpu.h>
#include <asm/spec-ctrl.h>
#include <asm/smp.h>
#include <asm/numa.h>
#include <asm/pci-direct.h>
#include <asm/delay.h>
#include <asm/debugreg.h>
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <asm/mtrr.h>
#include <asm/hwcap2.h>
#include <linux/numa.h>
#include <asm/numa.h>
#include <asm/asm.h>
#include <asm/bugs.h>
#include <asm/cpu.h>
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/hygon.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <asm/cpu.h>
#include <asm/smp.h>
#include <asm/numa.h>
#include <asm/cacheinfo.h>
#include <asm/spec-ctrl.h>
#include <asm/delay.h>
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <asm/cmdline.h>
#include <asm/traps.h>
#include <asm/resctrl.h>
#include <asm/numa.h>

#ifdef CONFIG_X86_64
#include <linux/topology.h>
Expand Down
Loading

0 comments on commit 97d052e

Please sign in to comment.