Skip to contentSkip to conversation

arm64: Implement WFE based spin wait for MCS spinlocks

RFC In review Jason Low 2 participants 3 messages Apr 14, 2016 – Apr 20, 2016 arm64

lore
Share & tools
lore

Jason Low

author
#0 lore raw

RFC 1/1 arm64: Implement WFE based spin wait for MCS spinlocks

Use WFE to avoid most spinning with MCS spinlocks. This is implemented with the new cmpwait() mechanism for comparing and waiting for the MCS locked value to change using LDXR + WFE.

---
 arch/arm64/include/asm/mcs_spinlock.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 arch/arm64/include/asm/mcs_spinlock.h
arch/arm64/include/asm/mcs_spinlock.h new file +21 -0
new file mode 100644
index 0000000..d295d9d
@@ -0,0 +1,21 @@
+#ifndef __ASM_MCS_SPINLOCK_H
+#define __ASM_MCS_SPINLOCK_H
+
+#define arch_mcs_spin_lock_contended(l)					\
+do {									\
+	int locked_val;							\
+	for (;;) {							\
+		locked_val = READ_ONCE(*l);				\
+		if (locked_val)						\
+			break;						\
+		cmpwait(l, locked_val);					\
+	}								\
+	smp_rmb();							\
+} while (0)
+
+#define arch_mcs_spin_unlock_contended(l)				\
+do {									\
+	smp_store_release(l, 1);					\
+} while (0)
+
+#endif  /* __ASM_MCS_SPINLOCK_H */
Signature · 1 line
2.1.4
#1 lore raw
Quoted 20 lines · Jason Low

Use WFE to avoid most spinning with MCS spinlocks. This is implemented with the new cmpwait() mechanism for comparing and waiting for the MCS locked value to change using LDXR + WFE.

---
 arch/arm64/include/asm/mcs_spinlock.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 arch/arm64/include/asm/mcs_spinlock.h
arch/arm64/include/asm/mcs_spinlock.h new file +4 -0
new file mode 100644
index 0000000..d295d9d
@@ -0,0 +1,21 @@
+#ifndef __ASM_MCS_SPINLOCK_H
+#define __ASM_MCS_SPINLOCK_H
+
+#define arch_mcs_spin_lock_contended(l)					\

arch/arm64/include/asm/mcs_spinlock.h line 14

Quoted 10 lines
arch/arm64/include/asm/mcs_spinlock.h new file +10 -0
+do {									\
+	int locked_val;							\
+	for (;;) {							\
+		locked_val = READ_ONCE(*l);				\
+		if (locked_val)						\
+			break;						\
+		cmpwait(l, locked_val);					\
+	}								\
+	smp_rmb();							\
+} while (0)

If you make the generic version use smp_cond_load_acquire() this isn't needed.

author
#2 lore raw
Quoted 26 lines · Peter Zijlstra
Quoted 25 lines · Jason Low

Use WFE to avoid most spinning with MCS spinlocks. This is implemented with the new cmpwait() mechanism for comparing and waiting for the MCS locked value to change using LDXR + WFE.

---
 arch/arm64/include/asm/mcs_spinlock.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 arch/arm64/include/asm/mcs_spinlock.h
arch/arm64/include/asm/mcs_spinlock.h new file +9 -0
new file mode 100644
index 0000000..d295d9d
@@ -0,0 +1,21 @@
+#ifndef __ASM_MCS_SPINLOCK_H
+#define __ASM_MCS_SPINLOCK_H
+
+#define arch_mcs_spin_lock_contended(l)					\
+do {									\
+	int locked_val;							\
+	for (;;) {							\
+		locked_val = READ_ONCE(*l);				\
+		if (locked_val)						\
Quoted 8 lines

arch/arm64/include/asm/mcs_spinlock.h line 14

Quoted 5 lines
arch/arm64/include/asm/mcs_spinlock.h new file +5 -0
+			break;						\
+		cmpwait(l, locked_val);					\
+	}								\
+	smp_rmb();							\
+} while (0)

If you make the generic version use smp_cond_load_acquire() this isn't needed.

Yup, in the email thread about modifying the generic version to use smp_cond_load_acquire(), I mentioned that overriding it in arch/arm64 would not be needed anymore.

Will made a suggestion about overriding it on arm64, but it turns out he was just referring to avoiding the immediate dependency on smp_cond_load_acquire().

Thanks,
Jason