Commit b13de4b7 authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/spinlock: remove compare and delay instruction

The CAD instruction never worked quite as expected for the spinlock
code. It has been disabled by default with git commit 61b0b016,
if the "cad" kernel parameter is specified it is enabled for both user
space and the spinlock code. Leave the option to enable the instruction
for user space but remove it from the spinlock code.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 02c503ff
...@@ -29,9 +29,8 @@ ...@@ -29,9 +29,8 @@
#define MACHINE_FLAG_TE _BITUL(11) #define MACHINE_FLAG_TE _BITUL(11)
#define MACHINE_FLAG_TLB_LC _BITUL(12) #define MACHINE_FLAG_TLB_LC _BITUL(12)
#define MACHINE_FLAG_VX _BITUL(13) #define MACHINE_FLAG_VX _BITUL(13)
#define MACHINE_FLAG_CAD _BITUL(14) #define MACHINE_FLAG_NX _BITUL(14)
#define MACHINE_FLAG_NX _BITUL(15) #define MACHINE_FLAG_GS _BITUL(15)
#define MACHINE_FLAG_GS _BITUL(16)
#define LPP_MAGIC _BITUL(31) #define LPP_MAGIC _BITUL(31)
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
...@@ -69,7 +68,6 @@ extern void detect_memory_memblock(void); ...@@ -69,7 +68,6 @@ extern void detect_memory_memblock(void);
#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
#define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC)
#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) #define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX)
#define MACHINE_HAS_CAD (S390_lowcore.machine_flags & MACHINE_FLAG_CAD)
#define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX)
#define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS)
......
...@@ -434,23 +434,16 @@ early_param("noexec", noexec_setup); ...@@ -434,23 +434,16 @@ early_param("noexec", noexec_setup);
static int __init cad_setup(char *str) static int __init cad_setup(char *str)
{ {
int val; bool enabled;
int rc;
get_option(&str, &val);
if (val && test_facility(128))
S390_lowcore.machine_flags |= MACHINE_FLAG_CAD;
return 0;
}
early_param("cad", cad_setup);
static int __init cad_init(void) rc = kstrtobool(str, &enabled);
{ if (!rc && enabled && test_facility(128))
if (MACHINE_HAS_CAD)
/* Enable problem state CAD. */ /* Enable problem state CAD. */
__ctl_set_bit(2, 3); __ctl_set_bit(2, 3);
return 0; return rc;
} }
early_initcall(cad_init); early_param("cad", cad_setup);
static __init void memmove_early(void *dst, const void *src, size_t n) static __init void memmove_early(void *dst, const void *src, size_t n)
{ {
......
...@@ -17,7 +17,7 @@ int spin_retry = -1; ...@@ -17,7 +17,7 @@ int spin_retry = -1;
static int __init spin_retry_init(void) static int __init spin_retry_init(void)
{ {
if (spin_retry < 0) if (spin_retry < 0)
spin_retry = MACHINE_HAS_CAD ? 10 : 1000; spin_retry = 1000;
return 0; return 0;
} }
early_initcall(spin_retry_init); early_initcall(spin_retry_init);
...@@ -32,11 +32,6 @@ static int __init spin_retry_setup(char *str) ...@@ -32,11 +32,6 @@ static int __init spin_retry_setup(char *str)
} }
__setup("spin_retry=", spin_retry_setup); __setup("spin_retry=", spin_retry_setup);
static inline void compare_and_delay(int *lock, int old)
{
asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock));
}
void arch_spin_lock_wait(arch_spinlock_t *lp) void arch_spin_lock_wait(arch_spinlock_t *lp)
{ {
int cpu = SPINLOCK_LOCKVAL; int cpu = SPINLOCK_LOCKVAL;
...@@ -60,8 +55,6 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) ...@@ -60,8 +55,6 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
/* Loop for a while on the lock value. */ /* Loop for a while on the lock value. */
count = spin_retry; count = spin_retry;
do { do {
if (MACHINE_HAS_CAD)
compare_and_delay(&lp->lock, owner);
owner = ACCESS_ONCE(lp->lock); owner = ACCESS_ONCE(lp->lock);
} while (owner && count-- > 0); } while (owner && count-- > 0);
if (!owner) if (!owner)
...@@ -105,8 +98,6 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) ...@@ -105,8 +98,6 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
/* Loop for a while on the lock value. */ /* Loop for a while on the lock value. */
count = spin_retry; count = spin_retry;
do { do {
if (MACHINE_HAS_CAD)
compare_and_delay(&lp->lock, owner);
owner = ACCESS_ONCE(lp->lock); owner = ACCESS_ONCE(lp->lock);
} while (owner && count-- > 0); } while (owner && count-- > 0);
if (!owner) if (!owner)
...@@ -135,8 +126,7 @@ int arch_spin_trylock_retry(arch_spinlock_t *lp) ...@@ -135,8 +126,7 @@ int arch_spin_trylock_retry(arch_spinlock_t *lp)
if (!owner) { if (!owner) {
if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu)) if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu))
return 1; return 1;
} else if (MACHINE_HAS_CAD) }
compare_and_delay(&lp->lock, owner);
} }
return 0; return 0;
} }
...@@ -159,11 +149,8 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) ...@@ -159,11 +149,8 @@ void _raw_read_lock_wait(arch_rwlock_t *rw)
} }
old = ACCESS_ONCE(rw->lock); old = ACCESS_ONCE(rw->lock);
owner = ACCESS_ONCE(rw->owner); owner = ACCESS_ONCE(rw->owner);
if (old < 0) { if (old < 0)
if (MACHINE_HAS_CAD)
compare_and_delay(&rw->lock, old);
continue; continue;
}
if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1)) if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1))
return; return;
} }
...@@ -177,11 +164,8 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw) ...@@ -177,11 +164,8 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw)
while (count-- > 0) { while (count-- > 0) {
old = ACCESS_ONCE(rw->lock); old = ACCESS_ONCE(rw->lock);
if (old < 0) { if (old < 0)
if (MACHINE_HAS_CAD)
compare_and_delay(&rw->lock, old);
continue; continue;
}
if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1)) if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1))
return 1; return 1;
} }
...@@ -212,8 +196,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, int prev) ...@@ -212,8 +196,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, int prev)
} }
if ((old & 0x7fffffff) == 0 && prev >= 0) if ((old & 0x7fffffff) == 0 && prev >= 0)
break; break;
if (MACHINE_HAS_CAD)
compare_and_delay(&rw->lock, old);
} }
} }
EXPORT_SYMBOL(_raw_write_lock_wait); EXPORT_SYMBOL(_raw_write_lock_wait);
...@@ -242,8 +224,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) ...@@ -242,8 +224,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
smp_mb(); smp_mb();
if ((old & 0x7fffffff) == 0 && prev >= 0) if ((old & 0x7fffffff) == 0 && prev >= 0)
break; break;
if (MACHINE_HAS_CAD)
compare_and_delay(&rw->lock, old);
} }
} }
EXPORT_SYMBOL(_raw_write_lock_wait); EXPORT_SYMBOL(_raw_write_lock_wait);
...@@ -257,11 +237,8 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw) ...@@ -257,11 +237,8 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw)
while (count-- > 0) { while (count-- > 0) {
old = ACCESS_ONCE(rw->lock); old = ACCESS_ONCE(rw->lock);
if (old) { if (old)
if (MACHINE_HAS_CAD)
compare_and_delay(&rw->lock, old);
continue; continue;
}
if (__atomic_cmpxchg_bool(&rw->lock, 0, 0x80000000)) if (__atomic_cmpxchg_bool(&rw->lock, 0, 0x80000000))
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment