s390/spinlock: remove compare and delay instruction
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 24 Mar 2017 16:00:45 +0000 (17:00 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 12 Apr 2017 06:43:33 +0000 (08:43 +0200)
The CAD instruction never worked quite as expected for the spinlock
code. It has been disabled by default with git commit 61b0b01686d48220,
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: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/setup.h
arch/s390/kernel/early.c
arch/s390/lib/spinlock.c

index 383bd8358a8c78d2c01095245071963d0133388f..cd78155b18296aec0e370b3f2a2315adf5c74a11 100644 (file)
@@ -29,9 +29,8 @@
 #define MACHINE_FLAG_TE                _BITUL(11)
 #define MACHINE_FLAG_TLB_LC    _BITUL(12)
 #define MACHINE_FLAG_VX                _BITUL(13)
-#define MACHINE_FLAG_CAD       _BITUL(14)
-#define MACHINE_FLAG_NX                _BITUL(15)
-#define MACHINE_FLAG_GS                _BITUL(16)
+#define MACHINE_FLAG_NX                _BITUL(14)
+#define MACHINE_FLAG_GS                _BITUL(15)
 
 #define LPP_MAGIC              _BITUL(31)
 #define LPP_PFAULT_PID_MASK    _AC(0xffffffff, UL)
@@ -69,7 +68,6 @@ extern void detect_memory_memblock(void);
 #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_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_GS         (S390_lowcore.machine_flags & MACHINE_FLAG_GS)
 
index 251391e3f8bcdac08f6ba359928e1d945125baf6..5d20182ee8aed5b9e2b07f76a69456d7259a3ed2 100644 (file)
@@ -434,23 +434,16 @@ early_param("noexec", noexec_setup);
 
 static int __init cad_setup(char *str)
 {
-       int val;
-
-       get_option(&str, &val);
-       if (val && test_facility(128))
-               S390_lowcore.machine_flags |= MACHINE_FLAG_CAD;
-       return 0;
-}
-early_param("cad", cad_setup);
+       bool enabled;
+       int rc;
 
-static int __init cad_init(void)
-{
-       if (MACHINE_HAS_CAD)
+       rc = kstrtobool(str, &enabled);
+       if (!rc && enabled && test_facility(128))
                /* Enable problem state CAD. */
                __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)
 {
index 3f4d0c69bbfe1cb0974de9e7cf174fd029be85a1..ffb15bd4c593f645f5ea9d226473af47a2be39a8 100644 (file)
@@ -17,7 +17,7 @@ int spin_retry = -1;
 static int __init spin_retry_init(void)
 {
        if (spin_retry < 0)
-               spin_retry = MACHINE_HAS_CAD ? 10 : 1000;
+               spin_retry = 1000;
        return 0;
 }
 early_initcall(spin_retry_init);
@@ -32,11 +32,6 @@ static int __init spin_retry_setup(char *str)
 }
 __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)
 {
        int cpu = SPINLOCK_LOCKVAL;
@@ -60,8 +55,6 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
                /* Loop for a while on the lock value. */
                count = spin_retry;
                do {
-                       if (MACHINE_HAS_CAD)
-                               compare_and_delay(&lp->lock, owner);
                        owner = ACCESS_ONCE(lp->lock);
                } while (owner && count-- > 0);
                if (!owner)
@@ -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. */
                count = spin_retry;
                do {
-                       if (MACHINE_HAS_CAD)
-                               compare_and_delay(&lp->lock, owner);
                        owner = ACCESS_ONCE(lp->lock);
                } while (owner && count-- > 0);
                if (!owner)
@@ -135,8 +126,7 @@ int arch_spin_trylock_retry(arch_spinlock_t *lp)
                if (!owner) {
                        if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu))
                                return 1;
-               } else if (MACHINE_HAS_CAD)
-                       compare_and_delay(&lp->lock, owner);
+               }
        }
        return 0;
 }
@@ -159,11 +149,8 @@ void _raw_read_lock_wait(arch_rwlock_t *rw)
                }
                old = ACCESS_ONCE(rw->lock);
                owner = ACCESS_ONCE(rw->owner);
-               if (old < 0) {
-                       if (MACHINE_HAS_CAD)
-                               compare_and_delay(&rw->lock, old);
+               if (old < 0)
                        continue;
-               }
                if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1))
                        return;
        }
@@ -177,11 +164,8 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw)
 
        while (count-- > 0) {
                old = ACCESS_ONCE(rw->lock);
-               if (old < 0) {
-                       if (MACHINE_HAS_CAD)
-                               compare_and_delay(&rw->lock, old);
+               if (old < 0)
                        continue;
-               }
                if (__atomic_cmpxchg_bool(&rw->lock, old, old + 1))
                        return 1;
        }
@@ -212,8 +196,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, int prev)
                }
                if ((old & 0x7fffffff) == 0 && prev >= 0)
                        break;
-               if (MACHINE_HAS_CAD)
-                       compare_and_delay(&rw->lock, old);
        }
 }
 EXPORT_SYMBOL(_raw_write_lock_wait);
@@ -242,8 +224,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
                        smp_mb();
                if ((old & 0x7fffffff) == 0 && prev >= 0)
                        break;
-               if (MACHINE_HAS_CAD)
-                       compare_and_delay(&rw->lock, old);
        }
 }
 EXPORT_SYMBOL(_raw_write_lock_wait);
@@ -257,11 +237,8 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw)
 
        while (count-- > 0) {
                old = ACCESS_ONCE(rw->lock);
-               if (old) {
-                       if (MACHINE_HAS_CAD)
-                               compare_and_delay(&rw->lock, old);
+               if (old)
                        continue;
-               }
                if (__atomic_cmpxchg_bool(&rw->lock, 0, 0x80000000))
                        return 1;
        }