diff options
author | Waiman Long <longman@redhat.com> | 2019-03-22 10:30:07 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-04-03 08:50:52 -0400 |
commit | 390a0c62c23cb026cd4664a66f6f45fed3a215f6 (patch) | |
tree | 4c165e3312c28313f0e83bac3121c09559bd73fd | |
parent | 46ad0840b1584b92b5ff2cc3ed0b011dd6b8e0f1 (diff) |
locking/rwsem: Remove rwsem-spinlock.c & use rwsem-xadd.c for all archs
Currently, we have two different implementation of rwsem:
1) CONFIG_RWSEM_GENERIC_SPINLOCK (rwsem-spinlock.c)
2) CONFIG_RWSEM_XCHGADD_ALGORITHM (rwsem-xadd.c)
As we are going to use a single generic implementation for rwsem-xadd.c
and no architecture-specific code will be needed, there is no point
in keeping two different implementations of rwsem. In most cases, the
performance of rwsem-spinlock.c will be worse. It also doesn't get all
the performance tuning and optimizations that had been implemented in
rwsem-xadd.c over the years.
For simplication, we are going to remove rwsem-spinlock.c and make all
architectures use a single implementation of rwsem - rwsem-xadd.c.
All references to RWSEM_GENERIC_SPINLOCK and RWSEM_XCHGADD_ALGORITHM
in the code are removed.
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-um@lists.infradead.org
Cc: linux-xtensa@linux-xtensa.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: nios2-dev@lists.rocketboards.org
Cc: openrisc@lists.librecores.org
Cc: uclinux-h8-devel@lists.sourceforge.jp
Link: https://lkml.kernel.org/r/20190322143008.21313-3-longman@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/alpha/Kconfig | 7 | ||||
-rw-r--r-- | arch/arc/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm64/Kconfig | 3 | ||||
-rw-r--r-- | arch/c6x/Kconfig | 3 | ||||
-rw-r--r-- | arch/csky/Kconfig | 3 | ||||
-rw-r--r-- | arch/h8300/Kconfig | 3 | ||||
-rw-r--r-- | arch/hexagon/Kconfig | 6 | ||||
-rw-r--r-- | arch/ia64/Kconfig | 4 | ||||
-rw-r--r-- | arch/m68k/Kconfig | 7 | ||||
-rw-r--r-- | arch/microblaze/Kconfig | 6 | ||||
-rw-r--r-- | arch/mips/Kconfig | 7 | ||||
-rw-r--r-- | arch/nds32/Kconfig | 3 | ||||
-rw-r--r-- | arch/nios2/Kconfig | 3 | ||||
-rw-r--r-- | arch/openrisc/Kconfig | 6 | ||||
-rw-r--r-- | arch/parisc/Kconfig | 6 | ||||
-rw-r--r-- | arch/powerpc/Kconfig | 7 | ||||
-rw-r--r-- | arch/riscv/Kconfig | 3 | ||||
-rw-r--r-- | arch/s390/Kconfig | 6 | ||||
-rw-r--r-- | arch/sh/Kconfig | 6 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 8 | ||||
-rw-r--r-- | arch/unicore32/Kconfig | 6 | ||||
-rw-r--r-- | arch/x86/Kconfig | 3 | ||||
-rw-r--r-- | arch/x86/um/Kconfig | 6 | ||||
-rw-r--r-- | arch/xtensa/Kconfig | 3 | ||||
-rw-r--r-- | include/linux/rwsem-spinlock.h | 47 | ||||
-rw-r--r-- | include/linux/rwsem.h | 5 | ||||
-rw-r--r-- | kernel/Kconfig.locks | 2 | ||||
-rw-r--r-- | kernel/locking/Makefile | 4 | ||||
-rw-r--r-- | kernel/locking/rwsem-spinlock.c | 339 | ||||
-rw-r--r-- | kernel/locking/rwsem.h | 3 |
31 files changed, 2 insertions, 520 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 584a6e114853..27c871227eee 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -49,13 +49,6 @@ config MMU | |||
49 | bool | 49 | bool |
50 | default y | 50 | default y |
51 | 51 | ||
52 | config RWSEM_GENERIC_SPINLOCK | ||
53 | bool | ||
54 | |||
55 | config RWSEM_XCHGADD_ALGORITHM | ||
56 | bool | ||
57 | default y | ||
58 | |||
59 | config ARCH_HAS_ILOG2_U32 | 52 | config ARCH_HAS_ILOG2_U32 |
60 | bool | 53 | bool |
61 | default n | 54 | default n |
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index c781e45d1d99..23e063df5d2c 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -63,9 +63,6 @@ config SCHED_OMIT_FRAME_POINTER | |||
63 | config GENERIC_CSUM | 63 | config GENERIC_CSUM |
64 | def_bool y | 64 | def_bool y |
65 | 65 | ||
66 | config RWSEM_GENERIC_SPINLOCK | ||
67 | def_bool y | ||
68 | |||
69 | config ARCH_DISCONTIGMEM_ENABLE | 66 | config ARCH_DISCONTIGMEM_ENABLE |
70 | def_bool n | 67 | def_bool n |
71 | 68 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 850b4805e2d1..c8b03e1c6c2a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -178,10 +178,6 @@ config TRACE_IRQFLAGS_SUPPORT | |||
178 | bool | 178 | bool |
179 | default !CPU_V7M | 179 | default !CPU_V7M |
180 | 180 | ||
181 | config RWSEM_XCHGADD_ALGORITHM | ||
182 | bool | ||
183 | default y | ||
184 | |||
185 | config ARCH_HAS_ILOG2_U32 | 181 | config ARCH_HAS_ILOG2_U32 |
186 | bool | 182 | bool |
187 | 183 | ||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 7e34b9eba5de..c62b9db2b5e8 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -237,9 +237,6 @@ config LOCKDEP_SUPPORT | |||
237 | config TRACE_IRQFLAGS_SUPPORT | 237 | config TRACE_IRQFLAGS_SUPPORT |
238 | def_bool y | 238 | def_bool y |
239 | 239 | ||
240 | config RWSEM_XCHGADD_ALGORITHM | ||
241 | def_bool y | ||
242 | |||
243 | config GENERIC_BUG | 240 | config GENERIC_BUG |
244 | def_bool y | 241 | def_bool y |
245 | depends on BUG | 242 | depends on BUG |
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index e5cd3c5f8399..ed92b5840c0a 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig | |||
@@ -27,9 +27,6 @@ config MMU | |||
27 | config FPU | 27 | config FPU |
28 | def_bool n | 28 | def_bool n |
29 | 29 | ||
30 | config RWSEM_GENERIC_SPINLOCK | ||
31 | def_bool y | ||
32 | |||
33 | config GENERIC_CALIBRATE_DELAY | 30 | config GENERIC_CALIBRATE_DELAY |
34 | def_bool y | 31 | def_bool y |
35 | 32 | ||
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 725a115759c9..6555d1781132 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig | |||
@@ -92,9 +92,6 @@ config GENERIC_HWEIGHT | |||
92 | config MMU | 92 | config MMU |
93 | def_bool y | 93 | def_bool y |
94 | 94 | ||
95 | config RWSEM_GENERIC_SPINLOCK | ||
96 | def_bool y | ||
97 | |||
98 | config STACKTRACE_SUPPORT | 95 | config STACKTRACE_SUPPORT |
99 | def_bool y | 96 | def_bool y |
100 | 97 | ||
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index c071da34e081..61c01db6c292 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig | |||
@@ -27,9 +27,6 @@ config H8300 | |||
27 | config CPU_BIG_ENDIAN | 27 | config CPU_BIG_ENDIAN |
28 | def_bool y | 28 | def_bool y |
29 | 29 | ||
30 | config RWSEM_GENERIC_SPINLOCK | ||
31 | def_bool y | ||
32 | |||
33 | config GENERIC_HWEIGHT | 30 | config GENERIC_HWEIGHT |
34 | def_bool y | 31 | def_bool y |
35 | 32 | ||
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index ac441680dcc0..3e54a53208d5 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig | |||
@@ -65,12 +65,6 @@ config GENERIC_CSUM | |||
65 | config GENERIC_IRQ_PROBE | 65 | config GENERIC_IRQ_PROBE |
66 | def_bool y | 66 | def_bool y |
67 | 67 | ||
68 | config RWSEM_GENERIC_SPINLOCK | ||
69 | def_bool n | ||
70 | |||
71 | config RWSEM_XCHGADD_ALGORITHM | ||
72 | def_bool y | ||
73 | |||
74 | config GENERIC_HWEIGHT | 68 | config GENERIC_HWEIGHT |
75 | def_bool y | 69 | def_bool y |
76 | 70 | ||
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 8d7396bd1790..73a26f04644e 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -83,10 +83,6 @@ config STACKTRACE_SUPPORT | |||
83 | config GENERIC_LOCKBREAK | 83 | config GENERIC_LOCKBREAK |
84 | def_bool n | 84 | def_bool n |
85 | 85 | ||
86 | config RWSEM_XCHGADD_ALGORITHM | ||
87 | bool | ||
88 | default y | ||
89 | |||
90 | config HUGETLB_PAGE_SIZE_VARIABLE | 86 | config HUGETLB_PAGE_SIZE_VARIABLE |
91 | bool | 87 | bool |
92 | depends on HUGETLB_PAGE | 88 | depends on HUGETLB_PAGE |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index b54206408f91..f5661f48019c 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -32,13 +32,6 @@ config M68K | |||
32 | config CPU_BIG_ENDIAN | 32 | config CPU_BIG_ENDIAN |
33 | def_bool y | 33 | def_bool y |
34 | 34 | ||
35 | config RWSEM_GENERIC_SPINLOCK | ||
36 | bool | ||
37 | default y | ||
38 | |||
39 | config RWSEM_XCHGADD_ALGORITHM | ||
40 | bool | ||
41 | |||
42 | config ARCH_HAS_ILOG2_U32 | 35 | config ARCH_HAS_ILOG2_U32 |
43 | bool | 36 | bool |
44 | 37 | ||
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index a51b965b3b82..a7a9a9d59f65 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig | |||
@@ -58,15 +58,9 @@ config CPU_LITTLE_ENDIAN | |||
58 | 58 | ||
59 | endchoice | 59 | endchoice |
60 | 60 | ||
61 | config RWSEM_GENERIC_SPINLOCK | ||
62 | def_bool y | ||
63 | |||
64 | config ZONE_DMA | 61 | config ZONE_DMA |
65 | def_bool y | 62 | def_bool y |
66 | 63 | ||
67 | config RWSEM_XCHGADD_ALGORITHM | ||
68 | bool | ||
69 | |||
70 | config ARCH_HAS_ILOG2_U32 | 64 | config ARCH_HAS_ILOG2_U32 |
71 | def_bool n | 65 | def_bool n |
72 | 66 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4a5f5b0ee9a9..b9c48b27162d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1037,13 +1037,6 @@ source "arch/mips/paravirt/Kconfig" | |||
1037 | 1037 | ||
1038 | endmenu | 1038 | endmenu |
1039 | 1039 | ||
1040 | config RWSEM_GENERIC_SPINLOCK | ||
1041 | bool | ||
1042 | default y | ||
1043 | |||
1044 | config RWSEM_XCHGADD_ALGORITHM | ||
1045 | bool | ||
1046 | |||
1047 | config GENERIC_HWEIGHT | 1040 | config GENERIC_HWEIGHT |
1048 | bool | 1041 | bool |
1049 | default y | 1042 | default y |
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index addb7f5f5264..55559ca0efe4 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig | |||
@@ -60,9 +60,6 @@ config GENERIC_LOCKBREAK | |||
60 | def_bool y | 60 | def_bool y |
61 | depends on PREEMPT | 61 | depends on PREEMPT |
62 | 62 | ||
63 | config RWSEM_GENERIC_SPINLOCK | ||
64 | def_bool y | ||
65 | |||
66 | config TRACE_IRQFLAGS_SUPPORT | 63 | config TRACE_IRQFLAGS_SUPPORT |
67 | def_bool y | 64 | def_bool y |
68 | 65 | ||
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 4ef15a61b7bc..56685fd45ed0 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig | |||
@@ -40,9 +40,6 @@ config NO_IOPORT_MAP | |||
40 | config FPU | 40 | config FPU |
41 | def_bool n | 41 | def_bool n |
42 | 42 | ||
43 | config RWSEM_GENERIC_SPINLOCK | ||
44 | def_bool y | ||
45 | |||
46 | config TRACE_IRQFLAGS_SUPPORT | 43 | config TRACE_IRQFLAGS_SUPPORT |
47 | def_bool n | 44 | def_bool n |
48 | 45 | ||
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index a5e361fbb75a..683511b8c9df 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig | |||
@@ -43,12 +43,6 @@ config CPU_BIG_ENDIAN | |||
43 | config MMU | 43 | config MMU |
44 | def_bool y | 44 | def_bool y |
45 | 45 | ||
46 | config RWSEM_GENERIC_SPINLOCK | ||
47 | def_bool y | ||
48 | |||
49 | config RWSEM_XCHGADD_ALGORITHM | ||
50 | def_bool n | ||
51 | |||
52 | config GENERIC_HWEIGHT | 46 | config GENERIC_HWEIGHT |
53 | def_bool y | 47 | def_bool y |
54 | 48 | ||
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index c8e621296092..f1ed8ddfe486 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -75,12 +75,6 @@ config GENERIC_LOCKBREAK | |||
75 | default y | 75 | default y |
76 | depends on SMP && PREEMPT | 76 | depends on SMP && PREEMPT |
77 | 77 | ||
78 | config RWSEM_GENERIC_SPINLOCK | ||
79 | def_bool y | ||
80 | |||
81 | config RWSEM_XCHGADD_ALGORITHM | ||
82 | bool | ||
83 | |||
84 | config ARCH_HAS_ILOG2_U32 | 78 | config ARCH_HAS_ILOG2_U32 |
85 | bool | 79 | bool |
86 | default n | 80 | default n |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2d0be82c3061..e5dd6aafaf68 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -103,13 +103,6 @@ config LOCKDEP_SUPPORT | |||
103 | bool | 103 | bool |
104 | default y | 104 | default y |
105 | 105 | ||
106 | config RWSEM_GENERIC_SPINLOCK | ||
107 | bool | ||
108 | |||
109 | config RWSEM_XCHGADD_ALGORITHM | ||
110 | bool | ||
111 | default y | ||
112 | |||
113 | config GENERIC_LOCKBREAK | 106 | config GENERIC_LOCKBREAK |
114 | bool | 107 | bool |
115 | default y | 108 | default y |
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index eb56c82d8aa1..0582260fb6c2 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig | |||
@@ -69,9 +69,6 @@ config STACKTRACE_SUPPORT | |||
69 | config TRACE_IRQFLAGS_SUPPORT | 69 | config TRACE_IRQFLAGS_SUPPORT |
70 | def_bool y | 70 | def_bool y |
71 | 71 | ||
72 | config RWSEM_GENERIC_SPINLOCK | ||
73 | def_bool y | ||
74 | |||
75 | config GENERIC_BUG | 72 | config GENERIC_BUG |
76 | def_bool y | 73 | def_bool y |
77 | depends on BUG | 74 | depends on BUG |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b6e3d0653002..c9300b437195 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -14,12 +14,6 @@ config LOCKDEP_SUPPORT | |||
14 | config STACKTRACE_SUPPORT | 14 | config STACKTRACE_SUPPORT |
15 | def_bool y | 15 | def_bool y |
16 | 16 | ||
17 | config RWSEM_GENERIC_SPINLOCK | ||
18 | bool | ||
19 | |||
20 | config RWSEM_XCHGADD_ALGORITHM | ||
21 | def_bool y | ||
22 | |||
23 | config ARCH_HAS_ILOG2_U32 | 17 | config ARCH_HAS_ILOG2_U32 |
24 | def_bool n | 18 | def_bool n |
25 | 19 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b1c91ea9a958..0be08d586d40 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -90,12 +90,6 @@ config ARCH_DEFCONFIG | |||
90 | default "arch/sh/configs/shx3_defconfig" if SUPERH32 | 90 | default "arch/sh/configs/shx3_defconfig" if SUPERH32 |
91 | default "arch/sh/configs/cayman_defconfig" if SUPERH64 | 91 | default "arch/sh/configs/cayman_defconfig" if SUPERH64 |
92 | 92 | ||
93 | config RWSEM_GENERIC_SPINLOCK | ||
94 | def_bool y | ||
95 | |||
96 | config RWSEM_XCHGADD_ALGORITHM | ||
97 | bool | ||
98 | |||
99 | config GENERIC_BUG | 93 | config GENERIC_BUG |
100 | def_bool y | 94 | def_bool y |
101 | depends on BUG && SUPERH32 | 95 | depends on BUG && SUPERH32 |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 40f8f4f73fe8..16b620237816 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -191,14 +191,6 @@ config NR_CPUS | |||
191 | 191 | ||
192 | source "kernel/Kconfig.hz" | 192 | source "kernel/Kconfig.hz" |
193 | 193 | ||
194 | config RWSEM_GENERIC_SPINLOCK | ||
195 | bool | ||
196 | default y if SPARC32 | ||
197 | |||
198 | config RWSEM_XCHGADD_ALGORITHM | ||
199 | bool | ||
200 | default y if SPARC64 | ||
201 | |||
202 | config GENERIC_HWEIGHT | 194 | config GENERIC_HWEIGHT |
203 | bool | 195 | bool |
204 | default y | 196 | default y |
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 817d82608712..0d5869c9bf03 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig | |||
@@ -38,12 +38,6 @@ config STACKTRACE_SUPPORT | |||
38 | config LOCKDEP_SUPPORT | 38 | config LOCKDEP_SUPPORT |
39 | def_bool y | 39 | def_bool y |
40 | 40 | ||
41 | config RWSEM_GENERIC_SPINLOCK | ||
42 | def_bool y | ||
43 | |||
44 | config RWSEM_XCHGADD_ALGORITHM | ||
45 | bool | ||
46 | |||
47 | config ARCH_HAS_ILOG2_U32 | 41 | config ARCH_HAS_ILOG2_U32 |
48 | bool | 42 | bool |
49 | 43 | ||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5ad92419be19..84b184e016cd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -268,9 +268,6 @@ config ARCH_MAY_HAVE_PC_FDC | |||
268 | def_bool y | 268 | def_bool y |
269 | depends on ISA_DMA_API | 269 | depends on ISA_DMA_API |
270 | 270 | ||
271 | config RWSEM_XCHGADD_ALGORITHM | ||
272 | def_bool y | ||
273 | |||
274 | config GENERIC_CALIBRATE_DELAY | 271 | config GENERIC_CALIBRATE_DELAY |
275 | def_bool y | 272 | def_bool y |
276 | 273 | ||
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index a9e80e44178c..a8985e1f7432 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig | |||
@@ -32,12 +32,6 @@ config ARCH_DEFCONFIG | |||
32 | default "arch/um/configs/i386_defconfig" if X86_32 | 32 | default "arch/um/configs/i386_defconfig" if X86_32 |
33 | default "arch/um/configs/x86_64_defconfig" if X86_64 | 33 | default "arch/um/configs/x86_64_defconfig" if X86_64 |
34 | 34 | ||
35 | config RWSEM_XCHGADD_ALGORITHM | ||
36 | def_bool 64BIT | ||
37 | |||
38 | config RWSEM_GENERIC_SPINLOCK | ||
39 | def_bool !RWSEM_XCHGADD_ALGORITHM | ||
40 | |||
41 | config 3_LEVEL_PGTABLES | 35 | config 3_LEVEL_PGTABLES |
42 | bool "Three-level pagetables" if !64BIT | 36 | bool "Three-level pagetables" if !64BIT |
43 | default 64BIT | 37 | default 64BIT |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 4b9aafe766c5..35c8d91e6106 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -46,9 +46,6 @@ config XTENSA | |||
46 | with reasonable minimum requirements. The Xtensa Linux project has | 46 | with reasonable minimum requirements. The Xtensa Linux project has |
47 | a home page at <http://www.linux-xtensa.org/>. | 47 | a home page at <http://www.linux-xtensa.org/>. |
48 | 48 | ||
49 | config RWSEM_XCHGADD_ALGORITHM | ||
50 | def_bool y | ||
51 | |||
52 | config GENERIC_HWEIGHT | 49 | config GENERIC_HWEIGHT |
53 | def_bool y | 50 | def_bool y |
54 | 51 | ||
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h deleted file mode 100644 index e47568363e5e..000000000000 --- a/include/linux/rwsem-spinlock.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* rwsem-spinlock.h: fallback C implementation | ||
3 | * | ||
4 | * Copyright (c) 2001 David Howells (dhowells@redhat.com). | ||
5 | * - Derived partially from ideas by Andrea Arcangeli <andrea@suse.de> | ||
6 | * - Derived also from comments by Linus | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_RWSEM_SPINLOCK_H | ||
10 | #define _LINUX_RWSEM_SPINLOCK_H | ||
11 | |||
12 | #ifndef _LINUX_RWSEM_H | ||
13 | #error "please don't include linux/rwsem-spinlock.h directly, use linux/rwsem.h instead" | ||
14 | #endif | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | /* | ||
18 | * the rw-semaphore definition | ||
19 | * - if count is 0 then there are no active readers or writers | ||
20 | * - if count is +ve then that is the number of active readers | ||
21 | * - if count is -1 then there is one active writer | ||
22 | * - if wait_list is not empty, then there are processes waiting for the semaphore | ||
23 | */ | ||
24 | struct rw_semaphore { | ||
25 | __s32 count; | ||
26 | raw_spinlock_t wait_lock; | ||
27 | struct list_head wait_list; | ||
28 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
29 | struct lockdep_map dep_map; | ||
30 | #endif | ||
31 | }; | ||
32 | |||
33 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
34 | |||
35 | extern void __down_read(struct rw_semaphore *sem); | ||
36 | extern int __must_check __down_read_killable(struct rw_semaphore *sem); | ||
37 | extern int __down_read_trylock(struct rw_semaphore *sem); | ||
38 | extern void __down_write(struct rw_semaphore *sem); | ||
39 | extern int __must_check __down_write_killable(struct rw_semaphore *sem); | ||
40 | extern int __down_write_trylock(struct rw_semaphore *sem); | ||
41 | extern void __up_read(struct rw_semaphore *sem); | ||
42 | extern void __up_write(struct rw_semaphore *sem); | ||
43 | extern void __downgrade_write(struct rw_semaphore *sem); | ||
44 | extern int rwsem_is_locked(struct rw_semaphore *sem); | ||
45 | |||
46 | #endif /* __KERNEL__ */ | ||
47 | #endif /* _LINUX_RWSEM_SPINLOCK_H */ | ||
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 6e56006b2cb6..0fc41062c649 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h | |||
@@ -22,10 +22,6 @@ | |||
22 | 22 | ||
23 | struct rw_semaphore; | 23 | struct rw_semaphore; |
24 | 24 | ||
25 | #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK | ||
26 | #include <linux/rwsem-spinlock.h> /* use a generic implementation */ | ||
27 | #define __RWSEM_INIT_COUNT(name) .count = RWSEM_UNLOCKED_VALUE | ||
28 | #else | ||
29 | /* All arch specific implementations share the same struct */ | 25 | /* All arch specific implementations share the same struct */ |
30 | struct rw_semaphore { | 26 | struct rw_semaphore { |
31 | atomic_long_t count; | 27 | atomic_long_t count; |
@@ -65,7 +61,6 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem) | |||
65 | 61 | ||
66 | #define RWSEM_UNLOCKED_VALUE 0L | 62 | #define RWSEM_UNLOCKED_VALUE 0L |
67 | #define __RWSEM_INIT_COUNT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE) | 63 | #define __RWSEM_INIT_COUNT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE) |
68 | #endif | ||
69 | 64 | ||
70 | /* Common initializer macros and functions */ | 65 | /* Common initializer macros and functions */ |
71 | 66 | ||
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks index fbba478ae522..e335953fa704 100644 --- a/kernel/Kconfig.locks +++ b/kernel/Kconfig.locks | |||
@@ -229,7 +229,7 @@ config MUTEX_SPIN_ON_OWNER | |||
229 | 229 | ||
230 | config RWSEM_SPIN_ON_OWNER | 230 | config RWSEM_SPIN_ON_OWNER |
231 | def_bool y | 231 | def_bool y |
232 | depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW | 232 | depends on SMP && ARCH_SUPPORTS_ATOMIC_RMW |
233 | 233 | ||
234 | config LOCK_SPIN_ON_OWNER | 234 | config LOCK_SPIN_ON_OWNER |
235 | def_bool y | 235 | def_bool y |
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 392c7f23af76..1af83e9ce57d 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # and is generally not a function of system call inputs. | 3 | # and is generally not a function of system call inputs. |
4 | KCOV_INSTRUMENT := n | 4 | KCOV_INSTRUMENT := n |
5 | 5 | ||
6 | obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o | 6 | obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o rwsem-xadd.o |
7 | 7 | ||
8 | ifdef CONFIG_FUNCTION_TRACER | 8 | ifdef CONFIG_FUNCTION_TRACER |
9 | CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) | 9 | CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) |
@@ -25,8 +25,6 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o | |||
25 | obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o | 25 | obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o |
26 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o | 26 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o |
27 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | 27 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o |
28 | obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | ||
29 | obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o | ||
30 | obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o | 28 | obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o |
31 | obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o | 29 | obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o |
32 | obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o | 30 | obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o |
diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c deleted file mode 100644 index a7ffb2a96ede..000000000000 --- a/kernel/locking/rwsem-spinlock.c +++ /dev/null | |||
@@ -1,339 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* rwsem-spinlock.c: R/W semaphores: contention handling functions for | ||
3 | * generic spinlock implementation | ||
4 | * | ||
5 | * Copyright (c) 2001 David Howells (dhowells@redhat.com). | ||
6 | * - Derived partially from idea by Andrea Arcangeli <andrea@suse.de> | ||
7 | * - Derived also from comments by Linus | ||
8 | */ | ||
9 | #include <linux/rwsem.h> | ||
10 | #include <linux/sched/signal.h> | ||
11 | #include <linux/sched/debug.h> | ||
12 | #include <linux/export.h> | ||
13 | |||
14 | enum rwsem_waiter_type { | ||
15 | RWSEM_WAITING_FOR_WRITE, | ||
16 | RWSEM_WAITING_FOR_READ | ||
17 | }; | ||
18 | |||
19 | struct rwsem_waiter { | ||
20 | struct list_head list; | ||
21 | struct task_struct *task; | ||
22 | enum rwsem_waiter_type type; | ||
23 | }; | ||
24 | |||
25 | int rwsem_is_locked(struct rw_semaphore *sem) | ||
26 | { | ||
27 | int ret = 1; | ||
28 | unsigned long flags; | ||
29 | |||
30 | if (raw_spin_trylock_irqsave(&sem->wait_lock, flags)) { | ||
31 | ret = (sem->count != 0); | ||
32 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
33 | } | ||
34 | return ret; | ||
35 | } | ||
36 | EXPORT_SYMBOL(rwsem_is_locked); | ||
37 | |||
38 | /* | ||
39 | * initialise the semaphore | ||
40 | */ | ||
41 | void __init_rwsem(struct rw_semaphore *sem, const char *name, | ||
42 | struct lock_class_key *key) | ||
43 | { | ||
44 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
45 | /* | ||
46 | * Make sure we are not reinitializing a held semaphore: | ||
47 | */ | ||
48 | debug_check_no_locks_freed((void *)sem, sizeof(*sem)); | ||
49 | lockdep_init_map(&sem->dep_map, name, key, 0); | ||
50 | #endif | ||
51 | sem->count = 0; | ||
52 | raw_spin_lock_init(&sem->wait_lock); | ||
53 | INIT_LIST_HEAD(&sem->wait_list); | ||
54 | } | ||
55 | EXPORT_SYMBOL(__init_rwsem); | ||
56 | |||
57 | /* | ||
58 | * handle the lock release when processes blocked on it that can now run | ||
59 | * - if we come here, then: | ||
60 | * - the 'active count' _reached_ zero | ||
61 | * - the 'waiting count' is non-zero | ||
62 | * - the spinlock must be held by the caller | ||
63 | * - woken process blocks are discarded from the list after having task zeroed | ||
64 | * - writers are only woken if wakewrite is non-zero | ||
65 | */ | ||
66 | static inline struct rw_semaphore * | ||
67 | __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) | ||
68 | { | ||
69 | struct rwsem_waiter *waiter; | ||
70 | struct task_struct *tsk; | ||
71 | int woken; | ||
72 | |||
73 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); | ||
74 | |||
75 | if (waiter->type == RWSEM_WAITING_FOR_WRITE) { | ||
76 | if (wakewrite) | ||
77 | /* Wake up a writer. Note that we do not grant it the | ||
78 | * lock - it will have to acquire it when it runs. */ | ||
79 | wake_up_process(waiter->task); | ||
80 | goto out; | ||
81 | } | ||
82 | |||
83 | /* grant an infinite number of read locks to the front of the queue */ | ||
84 | woken = 0; | ||
85 | do { | ||
86 | struct list_head *next = waiter->list.next; | ||
87 | |||
88 | list_del(&waiter->list); | ||
89 | tsk = waiter->task; | ||
90 | /* | ||
91 | * Make sure we do not wakeup the next reader before | ||
92 | * setting the nil condition to grant the next reader; | ||
93 | * otherwise we could miss the wakeup on the other | ||
94 | * side and end up sleeping again. See the pairing | ||
95 | * in rwsem_down_read_failed(). | ||
96 | */ | ||
97 | smp_mb(); | ||
98 | waiter->task = NULL; | ||
99 | wake_up_process(tsk); | ||
100 | put_task_struct(tsk); | ||
101 | woken++; | ||
102 | if (next == &sem->wait_list) | ||
103 | break; | ||
104 | waiter = list_entry(next, struct rwsem_waiter, list); | ||
105 | } while (waiter->type != RWSEM_WAITING_FOR_WRITE); | ||
106 | |||
107 | sem->count += woken; | ||
108 | |||
109 | out: | ||
110 | return sem; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * wake a single writer | ||
115 | */ | ||
116 | static inline struct rw_semaphore * | ||
117 | __rwsem_wake_one_writer(struct rw_semaphore *sem) | ||
118 | { | ||
119 | struct rwsem_waiter *waiter; | ||
120 | |||
121 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); | ||
122 | wake_up_process(waiter->task); | ||
123 | |||
124 | return sem; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * get a read lock on the semaphore | ||
129 | */ | ||
130 | int __sched __down_read_common(struct rw_semaphore *sem, int state) | ||
131 | { | ||
132 | struct rwsem_waiter waiter; | ||
133 | unsigned long flags; | ||
134 | |||
135 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
136 | |||
137 | if (sem->count >= 0 && list_empty(&sem->wait_list)) { | ||
138 | /* granted */ | ||
139 | sem->count++; | ||
140 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
141 | goto out; | ||
142 | } | ||
143 | |||
144 | /* set up my own style of waitqueue */ | ||
145 | waiter.task = current; | ||
146 | waiter.type = RWSEM_WAITING_FOR_READ; | ||
147 | get_task_struct(current); | ||
148 | |||
149 | list_add_tail(&waiter.list, &sem->wait_list); | ||
150 | |||
151 | /* wait to be given the lock */ | ||
152 | for (;;) { | ||
153 | if (!waiter.task) | ||
154 | break; | ||
155 | if (signal_pending_state(state, current)) | ||
156 | goto out_nolock; | ||
157 | set_current_state(state); | ||
158 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
159 | schedule(); | ||
160 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
161 | } | ||
162 | |||
163 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
164 | out: | ||
165 | return 0; | ||
166 | |||
167 | out_nolock: | ||
168 | /* | ||
169 | * We didn't take the lock, so that there is a writer, which | ||
170 | * is owner or the first waiter of the sem. If it's a waiter, | ||
171 | * it will be woken by current owner. Not need to wake anybody. | ||
172 | */ | ||
173 | list_del(&waiter.list); | ||
174 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
175 | return -EINTR; | ||
176 | } | ||
177 | |||
178 | void __sched __down_read(struct rw_semaphore *sem) | ||
179 | { | ||
180 | __down_read_common(sem, TASK_UNINTERRUPTIBLE); | ||
181 | } | ||
182 | |||
183 | int __sched __down_read_killable(struct rw_semaphore *sem) | ||
184 | { | ||
185 | return __down_read_common(sem, TASK_KILLABLE); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * trylock for reading -- returns 1 if successful, 0 if contention | ||
190 | */ | ||
191 | int __down_read_trylock(struct rw_semaphore *sem) | ||
192 | { | ||
193 | unsigned long flags; | ||
194 | int ret = 0; | ||
195 | |||
196 | |||
197 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
198 | |||
199 | if (sem->count >= 0 && list_empty(&sem->wait_list)) { | ||
200 | /* granted */ | ||
201 | sem->count++; | ||
202 | ret = 1; | ||
203 | } | ||
204 | |||
205 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
206 | |||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * get a write lock on the semaphore | ||
212 | */ | ||
213 | int __sched __down_write_common(struct rw_semaphore *sem, int state) | ||
214 | { | ||
215 | struct rwsem_waiter waiter; | ||
216 | unsigned long flags; | ||
217 | int ret = 0; | ||
218 | |||
219 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
220 | |||
221 | /* set up my own style of waitqueue */ | ||
222 | waiter.task = current; | ||
223 | waiter.type = RWSEM_WAITING_FOR_WRITE; | ||
224 | list_add_tail(&waiter.list, &sem->wait_list); | ||
225 | |||
226 | /* wait for someone to release the lock */ | ||
227 | for (;;) { | ||
228 | /* | ||
229 | * That is the key to support write lock stealing: allows the | ||
230 | * task already on CPU to get the lock soon rather than put | ||
231 | * itself into sleep and waiting for system woke it or someone | ||
232 | * else in the head of the wait list up. | ||
233 | */ | ||
234 | if (sem->count == 0) | ||
235 | break; | ||
236 | if (signal_pending_state(state, current)) | ||
237 | goto out_nolock; | ||
238 | |||
239 | set_current_state(state); | ||
240 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
241 | schedule(); | ||
242 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
243 | } | ||
244 | /* got the lock */ | ||
245 | sem->count = -1; | ||
246 | list_del(&waiter.list); | ||
247 | |||
248 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
249 | |||
250 | return ret; | ||
251 | |||
252 | out_nolock: | ||
253 | list_del(&waiter.list); | ||
254 | if (!list_empty(&sem->wait_list) && sem->count >= 0) | ||
255 | __rwsem_do_wake(sem, 0); | ||
256 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
257 | |||
258 | return -EINTR; | ||
259 | } | ||
260 | |||
261 | void __sched __down_write(struct rw_semaphore *sem) | ||
262 | { | ||
263 | __down_write_common(sem, TASK_UNINTERRUPTIBLE); | ||
264 | } | ||
265 | |||
266 | int __sched __down_write_killable(struct rw_semaphore *sem) | ||
267 | { | ||
268 | return __down_write_common(sem, TASK_KILLABLE); | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * trylock for writing -- returns 1 if successful, 0 if contention | ||
273 | */ | ||
274 | int __down_write_trylock(struct rw_semaphore *sem) | ||
275 | { | ||
276 | unsigned long flags; | ||
277 | int ret = 0; | ||
278 | |||
279 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
280 | |||
281 | if (sem->count == 0) { | ||
282 | /* got the lock */ | ||
283 | sem->count = -1; | ||
284 | ret = 1; | ||
285 | } | ||
286 | |||
287 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
288 | |||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * release a read lock on the semaphore | ||
294 | */ | ||
295 | void __up_read(struct rw_semaphore *sem) | ||
296 | { | ||
297 | unsigned long flags; | ||
298 | |||
299 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
300 | |||
301 | if (--sem->count == 0 && !list_empty(&sem->wait_list)) | ||
302 | sem = __rwsem_wake_one_writer(sem); | ||
303 | |||
304 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * release a write lock on the semaphore | ||
309 | */ | ||
310 | void __up_write(struct rw_semaphore *sem) | ||
311 | { | ||
312 | unsigned long flags; | ||
313 | |||
314 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
315 | |||
316 | sem->count = 0; | ||
317 | if (!list_empty(&sem->wait_list)) | ||
318 | sem = __rwsem_do_wake(sem, 1); | ||
319 | |||
320 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * downgrade a write lock into a read lock | ||
325 | * - just wake up any readers at the front of the queue | ||
326 | */ | ||
327 | void __downgrade_write(struct rw_semaphore *sem) | ||
328 | { | ||
329 | unsigned long flags; | ||
330 | |||
331 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
332 | |||
333 | sem->count = 1; | ||
334 | if (!list_empty(&sem->wait_list)) | ||
335 | sem = __rwsem_do_wake(sem, 0); | ||
336 | |||
337 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
338 | } | ||
339 | |||
diff --git a/kernel/locking/rwsem.h b/kernel/locking/rwsem.h index 067e265fa5c1..45ee00236e03 100644 --- a/kernel/locking/rwsem.h +++ b/kernel/locking/rwsem.h | |||
@@ -153,7 +153,6 @@ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) | |||
153 | } | 153 | } |
154 | #endif | 154 | #endif |
155 | 155 | ||
156 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM | ||
157 | /* | 156 | /* |
158 | * lock for reading | 157 | * lock for reading |
159 | */ | 158 | */ |
@@ -260,5 +259,3 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
260 | if (tmp < 0) | 259 | if (tmp < 0) |
261 | rwsem_downgrade_wake(sem); | 260 | rwsem_downgrade_wake(sem); |
262 | } | 261 | } |
263 | |||
264 | #endif /* CONFIG_RWSEM_XCHGADD_ALGORITHM */ | ||