Skip to content

Commit 97d052e

Browse files
committed
Merge tag 'locking-urgent-2020-08-10' of git://git.kernel.org/pub/scm/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 ...
2 parents 086ba2e + 0cd39f4 commit 97d052e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+501
-203
lines changed

Documentation/locking/seqlock.rst

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,58 @@ Read path::
8787
} while (read_seqcount_retry(&foo_seqcount, seq));
8888

8989

90+
.. _seqcount_locktype_t:
91+
92+
Sequence counters with associated locks (``seqcount_LOCKTYPE_t``)
93+
-----------------------------------------------------------------
94+
95+
As discussed at :ref:`seqcount_t`, sequence count write side critical
96+
sections must be serialized and non-preemptible. This variant of
97+
sequence counters associate the lock used for writer serialization at
98+
initialization time, which enables lockdep to validate that the write
99+
side critical sections are properly serialized.
100+
101+
This lock association is a NOOP if lockdep is disabled and has neither
102+
storage nor runtime overhead. If lockdep is enabled, the lock pointer is
103+
stored in struct seqcount and lockdep's "lock is held" assertions are
104+
injected at the beginning of the write side critical section to validate
105+
that it is properly protected.
106+
107+
For lock types which do not implicitly disable preemption, preemption
108+
protection is enforced in the write side function.
109+
110+
The following sequence counters with associated locks are defined:
111+
112+
- ``seqcount_spinlock_t``
113+
- ``seqcount_raw_spinlock_t``
114+
- ``seqcount_rwlock_t``
115+
- ``seqcount_mutex_t``
116+
- ``seqcount_ww_mutex_t``
117+
118+
The plain seqcount read and write APIs branch out to the specific
119+
seqcount_LOCKTYPE_t implementation at compile-time. This avoids kernel
120+
API explosion per each new seqcount LOCKTYPE.
121+
122+
Initialization (replace "LOCKTYPE" with one of the supported locks)::
123+
124+
/* dynamic */
125+
seqcount_LOCKTYPE_t foo_seqcount;
126+
seqcount_LOCKTYPE_init(&foo_seqcount, &lock);
127+
128+
/* static */
129+
static seqcount_LOCKTYPE_t foo_seqcount =
130+
SEQCNT_LOCKTYPE_ZERO(foo_seqcount, &lock);
131+
132+
/* C99 struct init */
133+
struct {
134+
.seq = SEQCNT_LOCKTYPE_ZERO(foo.seq, &lock),
135+
} foo;
136+
137+
Write path: same as in :ref:`seqcount_t`, while running from a context
138+
with the associated LOCKTYPE lock acquired.
139+
140+
Read path: same as in :ref:`seqcount_t`.
141+
90142
.. _seqlock_t:
91143

92144
Sequential locks (``seqlock_t``)

arch/ia64/include/asm/smp.h

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <linux/bitops.h>
1919
#include <linux/irqreturn.h>
2020

21-
#include <asm/io.h>
2221
#include <asm/param.h>
2322
#include <asm/processor.h>
2423
#include <asm/ptrace.h>
@@ -44,11 +43,6 @@ ia64_get_lid (void)
4443

4544
#ifdef CONFIG_SMP
4645

47-
#define XTP_OFFSET 0x1e0008
48-
49-
#define SMP_IRQ_REDIRECTION (1 << 0)
50-
#define SMP_IPI_REDIRECTION (1 << 1)
51-
5246
#define raw_smp_processor_id() (current_thread_info()->cpu)
5347

5448
extern struct smp_boot_data {
@@ -62,7 +56,6 @@ extern cpumask_t cpu_core_map[NR_CPUS];
6256
DECLARE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
6357
extern int smp_num_siblings;
6458
extern void __iomem *ipi_base_addr;
65-
extern unsigned char smp_int_redirect;
6659

6760
extern volatile int ia64_cpu_to_sapicid[];
6861
#define cpu_physical_id(i) ia64_cpu_to_sapicid[i]
@@ -84,34 +77,6 @@ cpu_logical_id (int cpuid)
8477
return i;
8578
}
8679

87-
/*
88-
* XTP control functions:
89-
* min_xtp : route all interrupts to this CPU
90-
* normal_xtp: nominal XTP value
91-
* max_xtp : never deliver interrupts to this CPU.
92-
*/
93-
94-
static inline void
95-
min_xtp (void)
96-
{
97-
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
98-
writeb(0x00, ipi_base_addr + XTP_OFFSET); /* XTP to min */
99-
}
100-
101-
static inline void
102-
normal_xtp (void)
103-
{
104-
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
105-
writeb(0x08, ipi_base_addr + XTP_OFFSET); /* XTP normal */
106-
}
107-
108-
static inline void
109-
max_xtp (void)
110-
{
111-
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
112-
writeb(0x0f, ipi_base_addr + XTP_OFFSET); /* Set XTP to max */
113-
}
114-
11580
/* Upping and downing of CPUs */
11681
extern int __cpu_disable (void);
11782
extern void __cpu_die (unsigned int cpu);

arch/ia64/include/asm/xtp.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ASM_IA64_XTP_H
3+
#define _ASM_IA64_XTP_H
4+
5+
#include <asm/io.h>
6+
7+
#ifdef CONFIG_SMP
8+
9+
#define XTP_OFFSET 0x1e0008
10+
11+
#define SMP_IRQ_REDIRECTION (1 << 0)
12+
#define SMP_IPI_REDIRECTION (1 << 1)
13+
14+
extern unsigned char smp_int_redirect;
15+
16+
/*
17+
* XTP control functions:
18+
* min_xtp : route all interrupts to this CPU
19+
* normal_xtp: nominal XTP value
20+
* max_xtp : never deliver interrupts to this CPU.
21+
*/
22+
23+
static inline void
24+
min_xtp (void)
25+
{
26+
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
27+
writeb(0x00, ipi_base_addr + XTP_OFFSET); /* XTP to min */
28+
}
29+
30+
static inline void
31+
normal_xtp (void)
32+
{
33+
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
34+
writeb(0x08, ipi_base_addr + XTP_OFFSET); /* XTP normal */
35+
}
36+
37+
static inline void
38+
max_xtp (void)
39+
{
40+
if (smp_int_redirect & SMP_IRQ_REDIRECTION)
41+
writeb(0x0f, ipi_base_addr + XTP_OFFSET); /* Set XTP to max */
42+
}
43+
44+
#endif /* CONFIG_SMP */
45+
46+
#endif /* _ASM_IA64_XTP_Hy */

arch/ia64/kernel/iosapic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
#include <asm/iosapic.h>
9696
#include <asm/processor.h>
9797
#include <asm/ptrace.h>
98+
#include <asm/xtp.h>
9899

99100
#undef DEBUG_INTERRUPT_ROUTING
100101

arch/ia64/kernel/irq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/kernel_stat.h>
2626

2727
#include <asm/mca.h>
28+
#include <asm/xtp.h>
2829

2930
/*
3031
* 'what should we do if we get a hw irq event on an illegal vector'.

arch/ia64/kernel/process.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <linux/uaccess.h>
4848
#include <asm/unwind.h>
4949
#include <asm/user.h>
50+
#include <asm/xtp.h>
5051

5152
#include "entry.h"
5253

arch/ia64/kernel/sal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <asm/page.h>
1919
#include <asm/sal.h>
2020
#include <asm/pal.h>
21+
#include <asm/xtp.h>
2122

2223
__cacheline_aligned DEFINE_SPINLOCK(sal_lock);
2324
unsigned long sal_platform_features;

arch/ia64/kernel/setup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include <asm/tlbflush.h>
6666
#include <asm/unistd.h>
6767
#include <asm/uv/uv.h>
68+
#include <asm/xtp.h>
6869

6970
#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
7071
# error "struct cpuinfo_ia64 too big!"

arch/ia64/kernel/smp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <asm/tlbflush.h>
4646
#include <asm/unistd.h>
4747
#include <asm/mca.h>
48+
#include <asm/xtp.h>
4849

4950
/*
5051
* Note: alignment of 4 entries/cacheline was empirically determined

arch/parisc/include/asm/timex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef _ASMPARISC_TIMEX_H
88
#define _ASMPARISC_TIMEX_H
99

10+
#include <asm/special_insns.h>
1011

1112
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
1213

0 commit comments

Comments
 (0)