diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:42:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:42:32 -0500 |
commit | b3d6524ff7956c5a898d51a18eaecb62a60a2b84 (patch) | |
tree | cc049e7ec9edd9f5a76f286e04d8db9a1caa516a /arch/s390/lib/spinlock.c | |
parent | 07f80d41cf24b7e6e76cd97d420167932c9a7f82 (diff) | |
parent | 6a039eab53c01a58bfff95c78fc800ca7de27c77 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky:
- The remaining patches for the z13 machine support: kernel build
option for z13, the cache synonym avoidance, SMT support,
compare-and-delay for spinloops and the CES5S crypto adapater.
- The ftrace support for function tracing with the gcc hotpatch option.
This touches common code Makefiles, Steven is ok with the changes.
- The hypfs file system gets an extension to access diagnose 0x0c data
in user space for performance analysis for Linux running under z/VM.
- The iucv hvc console gets wildcard spport for the user id filtering.
- The cacheinfo code is converted to use the generic infrastructure.
- Cleanup and bug fixes.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (42 commits)
s390/process: free vx save area when releasing tasks
s390/hypfs: Eliminate hypfs interval
s390/hypfs: Add diagnose 0c support
s390/cacheinfo: don't use smp_processor_id() in preemptible context
s390/zcrypt: fixed domain scanning problem (again)
s390/smp: increase maximum value of NR_CPUS to 512
s390/jump label: use different nop instruction
s390/jump label: add sanity checks
s390/mm: correct missing space when reporting user process faults
s390/dasd: cleanup profiling
s390/dasd: add locking for global_profile access
s390/ftrace: hotpatch support for function tracing
ftrace: let notrace function attribute disable hotpatching if necessary
ftrace: allow architectures to specify ftrace compile options
s390: reintroduce diag 44 calls for cpu_relax()
s390/zcrypt: Add support for new crypto express (CEX5S) adapter.
s390/zcrypt: Number of supported ap domains is not retrievable.
s390/spinlock: add compare-and-delay to lock wait loops
s390/tape: remove redundant if statement
s390/hvc_iucv: add simple wildcard matches to the iucv allow filter
...
Diffstat (limited to 'arch/s390/lib/spinlock.c')
-rw-r--r-- | arch/s390/lib/spinlock.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 034a35a3e9c1..d6c9991f7797 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
@@ -12,7 +12,15 @@ | |||
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | 14 | ||
15 | int spin_retry = 1000; | 15 | int spin_retry = -1; |
16 | |||
17 | static int __init spin_retry_init(void) | ||
18 | { | ||
19 | if (spin_retry < 0) | ||
20 | spin_retry = MACHINE_HAS_CAD ? 10 : 1000; | ||
21 | return 0; | ||
22 | } | ||
23 | early_initcall(spin_retry_init); | ||
16 | 24 | ||
17 | /** | 25 | /** |
18 | * spin_retry= parameter | 26 | * spin_retry= parameter |
@@ -24,6 +32,11 @@ static int __init spin_retry_setup(char *str) | |||
24 | } | 32 | } |
25 | __setup("spin_retry=", spin_retry_setup); | 33 | __setup("spin_retry=", spin_retry_setup); |
26 | 34 | ||
35 | static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) | ||
36 | { | ||
37 | asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); | ||
38 | } | ||
39 | |||
27 | void arch_spin_lock_wait(arch_spinlock_t *lp) | 40 | void arch_spin_lock_wait(arch_spinlock_t *lp) |
28 | { | 41 | { |
29 | unsigned int cpu = SPINLOCK_LOCKVAL; | 42 | unsigned int cpu = SPINLOCK_LOCKVAL; |
@@ -46,6 +59,8 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) | |||
46 | /* Loop for a while on the lock value. */ | 59 | /* Loop for a while on the lock value. */ |
47 | count = spin_retry; | 60 | count = spin_retry; |
48 | do { | 61 | do { |
62 | if (MACHINE_HAS_CAD) | ||
63 | _raw_compare_and_delay(&lp->lock, owner); | ||
49 | owner = ACCESS_ONCE(lp->lock); | 64 | owner = ACCESS_ONCE(lp->lock); |
50 | } while (owner && count-- > 0); | 65 | } while (owner && count-- > 0); |
51 | if (!owner) | 66 | if (!owner) |
@@ -84,6 +99,8 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) | |||
84 | /* Loop for a while on the lock value. */ | 99 | /* Loop for a while on the lock value. */ |
85 | count = spin_retry; | 100 | count = spin_retry; |
86 | do { | 101 | do { |
102 | if (MACHINE_HAS_CAD) | ||
103 | _raw_compare_and_delay(&lp->lock, owner); | ||
87 | owner = ACCESS_ONCE(lp->lock); | 104 | owner = ACCESS_ONCE(lp->lock); |
88 | } while (owner && count-- > 0); | 105 | } while (owner && count-- > 0); |
89 | if (!owner) | 106 | if (!owner) |
@@ -100,11 +117,19 @@ EXPORT_SYMBOL(arch_spin_lock_wait_flags); | |||
100 | 117 | ||
101 | int arch_spin_trylock_retry(arch_spinlock_t *lp) | 118 | int arch_spin_trylock_retry(arch_spinlock_t *lp) |
102 | { | 119 | { |
120 | unsigned int cpu = SPINLOCK_LOCKVAL; | ||
121 | unsigned int owner; | ||
103 | int count; | 122 | int count; |
104 | 123 | ||
105 | for (count = spin_retry; count > 0; count--) | 124 | for (count = spin_retry; count > 0; count--) { |
106 | if (arch_spin_trylock_once(lp)) | 125 | owner = ACCESS_ONCE(lp->lock); |
107 | return 1; | 126 | /* Try to get the lock if it is free. */ |
127 | if (!owner) { | ||
128 | if (_raw_compare_and_swap(&lp->lock, 0, cpu)) | ||
129 | return 1; | ||
130 | } else if (MACHINE_HAS_CAD) | ||
131 | _raw_compare_and_delay(&lp->lock, owner); | ||
132 | } | ||
108 | return 0; | 133 | return 0; |
109 | } | 134 | } |
110 | EXPORT_SYMBOL(arch_spin_trylock_retry); | 135 | EXPORT_SYMBOL(arch_spin_trylock_retry); |
@@ -126,8 +151,11 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) | |||
126 | } | 151 | } |
127 | old = ACCESS_ONCE(rw->lock); | 152 | old = ACCESS_ONCE(rw->lock); |
128 | owner = ACCESS_ONCE(rw->owner); | 153 | owner = ACCESS_ONCE(rw->owner); |
129 | if ((int) old < 0) | 154 | if ((int) old < 0) { |
155 | if (MACHINE_HAS_CAD) | ||
156 | _raw_compare_and_delay(&rw->lock, old); | ||
130 | continue; | 157 | continue; |
158 | } | ||
131 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) | 159 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) |
132 | return; | 160 | return; |
133 | } | 161 | } |
@@ -141,8 +169,11 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw) | |||
141 | 169 | ||
142 | while (count-- > 0) { | 170 | while (count-- > 0) { |
143 | old = ACCESS_ONCE(rw->lock); | 171 | old = ACCESS_ONCE(rw->lock); |
144 | if ((int) old < 0) | 172 | if ((int) old < 0) { |
173 | if (MACHINE_HAS_CAD) | ||
174 | _raw_compare_and_delay(&rw->lock, old); | ||
145 | continue; | 175 | continue; |
176 | } | ||
146 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) | 177 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) |
147 | return 1; | 178 | return 1; |
148 | } | 179 | } |
@@ -173,6 +204,8 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) | |||
173 | } | 204 | } |
174 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) | 205 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) |
175 | break; | 206 | break; |
207 | if (MACHINE_HAS_CAD) | ||
208 | _raw_compare_and_delay(&rw->lock, old); | ||
176 | } | 209 | } |
177 | } | 210 | } |
178 | EXPORT_SYMBOL(_raw_write_lock_wait); | 211 | EXPORT_SYMBOL(_raw_write_lock_wait); |
@@ -201,6 +234,8 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) | |||
201 | smp_rmb(); | 234 | smp_rmb(); |
202 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) | 235 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) |
203 | break; | 236 | break; |
237 | if (MACHINE_HAS_CAD) | ||
238 | _raw_compare_and_delay(&rw->lock, old); | ||
204 | } | 239 | } |
205 | } | 240 | } |
206 | EXPORT_SYMBOL(_raw_write_lock_wait); | 241 | EXPORT_SYMBOL(_raw_write_lock_wait); |
@@ -214,8 +249,11 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw) | |||
214 | 249 | ||
215 | while (count-- > 0) { | 250 | while (count-- > 0) { |
216 | old = ACCESS_ONCE(rw->lock); | 251 | old = ACCESS_ONCE(rw->lock); |
217 | if (old) | 252 | if (old) { |
253 | if (MACHINE_HAS_CAD) | ||
254 | _raw_compare_and_delay(&rw->lock, old); | ||
218 | continue; | 255 | continue; |
256 | } | ||
219 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) | 257 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) |
220 | return 1; | 258 | return 1; |
221 | } | 259 | } |