Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1585645 > unrolled thread
| Started by | Stafford Horne <shorne@gmail.com> |
|---|---|
| First post | 2017-02-21 20:20 +0100 |
| Last post | 2017-02-21 20:30 +0100 |
| Articles | 16 on this page of 36 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v3 00/25] OpenRISC patches for 4.11 final call Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 16/25] openrisc: Add optimized memcpy routine Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 13/25] openrisc: Fix the bitmask for the unit present register Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 05/25] openrisc: head: refactor out tlb flush into it's own function Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 23/25] arch/openrisc/lib/memcpy.c: use correct OR1200 option Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 19/25] scripts/checkstack.pl: Add openrisc support Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 24/25] openrisc: Export ioremap symbols used by modules Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 21/25] openrisc: entry: Fix delay slot detection Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 04/25] openrisc: head: use THREAD_SIZE instead of magic constant Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 02/25] openrisc: add cache way information to cpuinfo Stafford Horne <shorne@gmail.com> - 2017-02-21 20:20 +0100
[PATCH v3 14/25] openrisc: Initial support for the idle state Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
Re: [PATCH v3 14/25] openrisc: Initial support for the idle state Joe Perches <joe@perches.com> - 2017-02-21 21:30 +0100
Re: [PATCH v3 14/25] openrisc: Initial support for the idle state Stafford Horne <shorne@gmail.com> - 2017-02-22 15:20 +0100
[PATCH v3 18/25] MAINTAINERS: Add the openrisc official repository Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
[PATCH v3 07/25] openrisc: add atomic bitops Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
[PATCH v3 09/25] openrisc: add optimized atomic operations Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
Re: [PATCH v3 09/25] openrisc: add optimized atomic operations Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:30 +0100
Re: [PATCH v3 09/25] openrisc: add optimized atomic operations Stafford Horne <shorne@gmail.com> - 2017-02-22 15:30 +0100
Re: [OpenRISC] [PATCH v3 09/25] openrisc: add optimized atomic operations Richard Henderson <rth@twiddle.net> - 2017-02-22 18:40 +0100
Re: [OpenRISC] [PATCH v3 09/25] openrisc: add optimized atomic operations Stafford Horne <shorne@gmail.com> - 2017-02-22 23:50 +0100
[PATCH v3 11/25] openrisc: add futex_atomic_* implementations Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
[PATCH v3 17/25] openrisc: Add .gitignore Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
[PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
Re: [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:30 +0100
Re: [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations Stafford Horne <shorne@gmail.com> - 2017-02-22 15:30 +0100
Re: [OpenRISC] [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations Richard Henderson <rth@twiddle.net> - 2017-02-22 18:40 +0100
Re: [OpenRISC] [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations Stafford Horne <shorne@gmail.com> - 2017-02-22 23:50 +0100
[PATCH v3 10/25] openrisc: add spinlock implementation Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:30 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:40 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:40 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 13:10 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:40 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 12:50 +0100
Re: [PATCH v3 10/25] openrisc: add spinlock implementation Peter Zijlstra <peterz@infradead.org> - 2017-02-22 13:10 +0100
[PATCH v3 20/25] openrisc: entry: Whitespace and comment cleanups Stafford Horne <shorne@gmail.com> - 2017-02-21 20:30 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-21 20:30 +0100 |
| Subject | [PATCH v3 11/25] openrisc: add futex_atomic_* implementations |
| Message-ID | <tdoin-6Y4-37@gated-at.bofh.it> |
| In reply to | #1585645 |
From: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Support for the futex_atomic_* operations by using the
load-link/store-conditional l.lwa/l.swa instructions.
Most openrisc cores provide these instructions now if not available,
emulation is provided.
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
[shorne@gmail.com: remove OPENRISC_HAVE_INST_LWA_SWA config suggesed by
Alan Cox https://lkml.org/lkml/2014/7/23/666]
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
arch/openrisc/include/asm/Kbuild | 1 -
arch/openrisc/include/asm/futex.h | 135 ++++++++++++++++++++++++++++++++++++++
2 files changed, 135 insertions(+), 1 deletion(-)
create mode 100644 arch/openrisc/include/asm/futex.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 1cedd63..a669c14 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -20,7 +20,6 @@ generic-y += exec.h
generic-y += fb.h
generic-y += fcntl.h
generic-y += ftrace.h
-generic-y += futex.h
generic-y += hardirq.h
generic-y += hw_irq.h
generic-y += ioctl.h
diff --git a/arch/openrisc/include/asm/futex.h b/arch/openrisc/include/asm/futex.h
new file mode 100644
index 0000000..7780873
--- /dev/null
+++ b/arch/openrisc/include/asm/futex.h
@@ -0,0 +1,135 @@
+#ifndef __ASM_OPENRISC_FUTEX_H
+#define __ASM_OPENRISC_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+({ \
+ __asm__ __volatile__ ( \
+ "1: l.lwa %0, %2 \n" \
+ insn "\n" \
+ "2: l.swa %2, %1 \n" \
+ " l.bnf 1b \n" \
+ " l.ori %1, r0, 0 \n" \
+ "3: \n" \
+ ".section .fixup,\"ax\" \n" \
+ "4: l.j 3b \n" \
+ " l.addi %1, r0, %3 \n" \
+ ".previous \n" \
+ ".section __ex_table,\"a\" \n" \
+ ".word 1b,4b,2b,4b \n" \
+ ".previous \n" \
+ : "=&r" (oldval), "=&r" (ret), "+m" (*uaddr) \
+ : "i" (-EFAULT), "r" (oparg) \
+ : "cc", "memory" \
+ ); \
+})
+
+static inline int
+futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+{
+ int op = (encoded_op >> 28) & 7;
+ int cmp = (encoded_op >> 24) & 15;
+ int oparg = (encoded_op << 8) >> 20;
+ int cmparg = (encoded_op << 20) >> 20;
+ int oldval = 0, ret;
+
+ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+ oparg = 1 << oparg;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ pagefault_disable();
+
+ switch (op) {
+ case FUTEX_OP_SET:
+ __futex_atomic_op("l.or %1,%4,%4", ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+ __futex_atomic_op("l.add %1,%0,%4", ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ __futex_atomic_op("l.or %1,%0,%4", ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ __futex_atomic_op("l.and %1,%0,%4", ret, oldval, uaddr, ~oparg);
+ break;
+ case FUTEX_OP_XOR:
+ __futex_atomic_op("l.xor %1,%0,%4", ret, oldval, uaddr, oparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ pagefault_enable();
+
+ if (!ret) {
+ switch (cmp) {
+ case FUTEX_OP_CMP_EQ:
+ ret = (oldval == cmparg);
+ break;
+ case FUTEX_OP_CMP_NE:
+ ret = (oldval != cmparg);
+ break;
+ case FUTEX_OP_CMP_LT:
+ ret = (oldval < cmparg);
+ break;
+ case FUTEX_OP_CMP_GE:
+ ret = (oldval >= cmparg);
+ break;
+ case FUTEX_OP_CMP_LE:
+ ret = (oldval <= cmparg);
+ break;
+ case FUTEX_OP_CMP_GT:
+ ret = (oldval > cmparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+ }
+ return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ int ret = 0;
+ u32 prev;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ __asm__ __volatile__ ( \
+ "1: l.lwa %1, %2 \n" \
+ " l.sfeq %1, %3 \n" \
+ " l.bnf 3f \n" \
+ " l.nop \n" \
+ "2: l.swa %2, %4 \n" \
+ " l.bnf 1b \n" \
+ " l.nop \n" \
+ "3: \n" \
+ ".section .fixup,\"ax\" \n" \
+ "4: l.j 3b \n" \
+ " l.addi %0, r0, %5 \n" \
+ ".previous \n" \
+ ".section __ex_table,\"a\" \n" \
+ ".word 1b,4b,2b,4b \n" \
+ ".previous \n" \
+ : "+r" (ret), "=&r" (prev), "+m" (*uaddr) \
+ : "r" (oldval), "r" (newval), "i" (-EFAULT) \
+ : "cc", "memory" \
+ );
+
+ *uval = prev;
+ return ret;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_OPENRISC_FUTEX_H */
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-21 20:30 +0100 |
| Subject | [PATCH v3 17/25] openrisc: Add .gitignore |
| Message-ID | <tdoin-6Y4-41@gated-at.bofh.it> |
| In reply to | #1585645 |
This helps to suppress the vmlinux.lds file. Signed-off-by: Stafford Horne <shorne@gmail.com> --- arch/openrisc/kernel/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/openrisc/kernel/.gitignore diff --git a/arch/openrisc/kernel/.gitignore b/arch/openrisc/kernel/.gitignore new file mode 100644 index 0000000..c5f676c --- /dev/null +++ b/arch/openrisc/kernel/.gitignore @@ -0,0 +1 @@ +vmlinux.lds -- 2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-21 20:30 +0100 |
| Subject | [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations |
| Message-ID | <tdoin-6Y4-43@gated-at.bofh.it> |
| In reply to | #1585645 |
From: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Optimized version that make use of the l.lwa and l.swa atomic instruction
pair.
Most openrisc cores provide these instructions now, if not available
emulation is provided.
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
[shorne@gmail.com: remove OPENRISC_HAVE_INST_LWA_SWA config suggesed by
Alan Cox https://lkml.org/lkml/2014/7/23/666]
[shorne@gmail.com: fixed unused calculated value compiler warning in
define cmpxchg]
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
arch/openrisc/include/asm/Kbuild | 2 -
arch/openrisc/include/asm/cmpxchg.h | 82 +++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 2 deletions(-)
create mode 100644 arch/openrisc/include/asm/cmpxchg.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 6dd177d..15e6ed5 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -10,8 +10,6 @@ generic-y += bugs.h
generic-y += cacheflush.h
generic-y += checksum.h
generic-y += clkdev.h
-generic-y += cmpxchg-local.h
-generic-y += cmpxchg.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
diff --git a/arch/openrisc/include/asm/cmpxchg.h b/arch/openrisc/include/asm/cmpxchg.h
new file mode 100644
index 0000000..6d73c7b
--- /dev/null
+++ b/arch/openrisc/include/asm/cmpxchg.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __ASM_OPENRISC_CMPXCHG_H
+#define __ASM_OPENRISC_CMPXCHG_H
+
+#include <linux/types.h>
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+ if (size != 4) {
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+ }
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.sfeq %0, %2 \n"
+ " l.bnf 1f \n"
+ " l.nop \n"
+ " l.swa 0(%1), %3 \n"
+ " l.bnf 1b \n"
+ "1: l.nop \n"
+ : "=&r"(old)
+ : "r"(ptr), "r"(old), "r"(new)
+ : "cc", "memory");
+
+ return old;
+}
+
+#define cmpxchg(ptr, o, n) \
+ ({ \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))); \
+ })
+
+/*
+ * This function doesn't exist, so you'll get a linker error if
+ * something tries to do an invalidly-sized xchg().
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+ int size)
+{
+ if (size != 4) {
+ __xchg_called_with_bad_pointer();
+ return val;
+ }
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.swa 0(%1), %2 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ : "=&r"(val)
+ : "r"(ptr), "r"(val)
+ : "cc", "memory");
+
+ return val;
+}
+
+#define xchg(ptr, with) \
+ ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), sizeof(*(ptr))))
+
+#endif /* __ASM_OPENRISC_CMPXCHG_H */
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:30 +0100 |
| Subject | Re: [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations |
| Message-ID | <tdDho-V3-7@gated-at.bofh.it> |
| In reply to | #1585678 |
On Wed, Feb 22, 2017 at 04:11:37AM +0900, Stafford Horne wrote: > + __asm__ __volatile__( > + "1: l.lwa %0, 0(%1) \n" > + " l.sfeq %0, %2 \n" > + " l.bnf 1f \n" > + " l.nop \n" > + " l.swa 0(%1), %3 \n" > + " l.bnf 1b \n" > + "1: l.nop \n" > + : "=&r"(old) > + : "r"(ptr), "r"(old), "r"(new) > + : "cc", "memory"); I just noticed this, but having both labels have the same name is somewhat confusing.
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-22 15:30 +0100 |
| Subject | Re: [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations |
| Message-ID | <tdG5z-2Z4-7@gated-at.bofh.it> |
| In reply to | #1586077 |
On Wed, Feb 22, 2017 at 12:19:40PM +0100, Peter Zijlstra wrote: > On Wed, Feb 22, 2017 at 04:11:37AM +0900, Stafford Horne wrote: > > + __asm__ __volatile__( > > + "1: l.lwa %0, 0(%1) \n" > > + " l.sfeq %0, %2 \n" > > + " l.bnf 1f \n" > > + " l.nop \n" > > + " l.swa 0(%1), %3 \n" > > + " l.bnf 1b \n" > > + "1: l.nop \n" > > + : "=&r"(old) > > + : "r"(ptr), "r"(old), "r"(new) > > + : "cc", "memory"); > > I just noticed this, but having both labels have the same name is > somewhat confusing. Right, better to use '2' for the second one.
[toc] | [prev] | [next] | [standalone]
| From | Richard Henderson <rth@twiddle.net> |
|---|---|
| Date | 2017-02-22 18:40 +0100 |
| Subject | Re: [OpenRISC] [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations |
| Message-ID | <tdJ3s-5dB-11@gated-at.bofh.it> |
| In reply to | #1586192 |
On 02/23/2017 01:20 AM, Stafford Horne wrote: > On Wed, Feb 22, 2017 at 12:19:40PM +0100, Peter Zijlstra wrote: >> On Wed, Feb 22, 2017 at 04:11:37AM +0900, Stafford Horne wrote: >>> + __asm__ __volatile__( >>> + "1: l.lwa %0, 0(%1) \n" >>> + " l.sfeq %0, %2 \n" >>> + " l.bnf 1f \n" >>> + " l.nop \n" >>> + " l.swa 0(%1), %3 \n" >>> + " l.bnf 1b \n" >>> + "1: l.nop \n" >>> + : "=&r"(old) >>> + : "r"(ptr), "r"(old), "r"(new) >>> + : "cc", "memory"); >> >> I just noticed this, but having both labels have the same name is >> somewhat confusing. > > Right, better to use '2' for the second one. Better still to put the second label after the delay-slot nop. You don't need to execute that on the way out. r~
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-22 23:50 +0100 |
| Subject | Re: [OpenRISC] [PATCH v3 08/25] openrisc: add cmpxchg and xchg implementations |
| Message-ID | <tdNTs-eQ-13@gated-at.bofh.it> |
| In reply to | #1586344 |
On Thu, Feb 23, 2017 at 04:30:35AM +1100, Richard Henderson wrote: > On 02/23/2017 01:20 AM, Stafford Horne wrote: > > On Wed, Feb 22, 2017 at 12:19:40PM +0100, Peter Zijlstra wrote: > > > On Wed, Feb 22, 2017 at 04:11:37AM +0900, Stafford Horne wrote: > > > > + __asm__ __volatile__( > > > > + "1: l.lwa %0, 0(%1) \n" > > > > + " l.sfeq %0, %2 \n" > > > > + " l.bnf 1f \n" > > > > + " l.nop \n" > > > > + " l.swa 0(%1), %3 \n" > > > > + " l.bnf 1b \n" > > > > + "1: l.nop \n" > > > > + : "=&r"(old) > > > > + : "r"(ptr), "r"(old), "r"(new) > > > > + : "cc", "memory"); > > > > > > I just noticed this, but having both labels have the same name is > > > somewhat confusing. > > > > Right, better to use '2' for the second one. > > Better still to put the second label after the delay-slot nop. > You don't need to execute that on the way out. Right, thats a good point, lots of cases like this. I will go through them. > r~ >
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-21 20:30 +0100 |
| Subject | [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdoim-6Y4-33@gated-at.bofh.it> |
| In reply to | #1585645 |
From: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Heavily based on the ARM implementation, this adds
ticket spinlock support for OpenRISC.
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
[shorne@gmail.com: fix tabs vs space checkpatch warning]
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
arch/openrisc/include/asm/spinlock.h | 232 ++++++++++++++++++++++++++++-
arch/openrisc/include/asm/spinlock_types.h | 28 ++++
2 files changed, 259 insertions(+), 1 deletion(-)
create mode 100644 arch/openrisc/include/asm/spinlock_types.h
diff --git a/arch/openrisc/include/asm/spinlock.h b/arch/openrisc/include/asm/spinlock.h
index fd00a3a..adf62a6 100644
--- a/arch/openrisc/include/asm/spinlock.h
+++ b/arch/openrisc/include/asm/spinlock.h
@@ -9,6 +9,9 @@
* Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
* Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
* et al.
+ * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+ *
+ * Ticket spinlocks, based on the ARM implementation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +22,233 @@
#ifndef __ASM_OPENRISC_SPINLOCK_H
#define __ASM_OPENRISC_SPINLOCK_H
-#error "or32 doesn't do SMP yet"
+#include <asm/spinlock_types.h>
+
+#define arch_spin_unlock_wait(lock) \
+ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
+
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ u32 newval;
+ arch_spinlock_t lockval;
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%2) \n"
+ " l.add %1, %0, %3 \n"
+ " l.swa 0(%2), %1 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ : "=&r" (lockval), "=&r" (newval)
+ : "r" (&lock->slock), "r" (1 << TICKET_SHIFT)
+ : "cc", "memory");
+
+ while (lockval.tickets.next != lockval.tickets.owner)
+ lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);
+
+ smp_mb();
+}
+
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ unsigned long contended, tmp;
+ u32 slock;
+
+ /* contended = (lock->tickets.owner != lock->tickets.next) */
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%3) \n"
+ " l.srli %1, %0, 16 \n"
+ " l.andi %2, %0, 0xffff \n"
+ " l.sfeq %1, %2 \n"
+ " l.bnf 1f \n"
+ " l.ori %1, r0, 1 \n"
+ " l.add %0, %0, %4 \n"
+ " l.swa 0(%3), %0 \n"
+ " l.bnf 1b \n"
+ " l.ori %1, r0, 0 \n"
+ "1: \n"
+ : "=&r" (slock), "=&r" (contended), "=&r" (tmp)
+ : "r" (&lock->slock), "r" (1 << TICKET_SHIFT)
+ : "cc", "memory");
+
+ if (!contended) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ smp_mb();
+ lock->tickets.owner++;
+}
+
+static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
+{
+ return lock.tickets.owner == lock.tickets.next;
+}
+
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ return !arch_spin_value_unlocked(ACCESS_ONCE(*lock));
+}
+
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ struct __raw_tickets tickets = ACCESS_ONCE(lock->tickets);
+
+ return (tickets.next - tickets.owner) > 1;
+}
+#define arch_spin_is_contended arch_spin_is_contended
+
+/*
+ * RWLOCKS
+ *
+ *
+ * Write locks are easy - we just set bit 31. When unlocking, we can
+ * just write zero since the lock is exclusively held.
+ */
+
+static inline void arch_write_lock(arch_rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.sfeqi %0, 0 \n"
+ " l.bnf 1f \n"
+ " l.nop \n"
+ " l.swa 0(%1), %2 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ "1: \n"
+ : "=&r" (tmp)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc", "memory");
+
+ smp_mb();
+}
+
+static inline int arch_write_trylock(arch_rwlock_t *rw)
+{
+ unsigned long contended;
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.sfeqi %0, 0 \n"
+ " l.bnf 1f \n"
+ " l.nop \n"
+ " l.swa 0(%1), %2 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ "1: \n"
+ : "=&r" (contended)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc", "memory");
+
+ if (!contended) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline void arch_write_unlock(arch_rwlock_t *rw)
+{
+ smp_mb();
+ rw->lock = 0;
+}
+
+/* write_can_lock - would write_trylock() succeed? */
+#define arch_write_can_lock(x) (ACCESS_ONCE((x)->lock) == 0)
+
+/*
+ * Read locks are a bit more hairy:
+ * - Exclusively load the lock value.
+ * - Increment it.
+ * - Store new lock value if positive, and we still own this location.
+ * If the value is negative, we've already failed.
+ * - If we failed to store the value, we want a negative result.
+ * - If we failed, try again.
+ * Unlocking is similarly hairy. We may have multiple read locks
+ * currently active. However, we know we won't have any write
+ * locks.
+ */
+static inline void arch_read_lock(arch_rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.sfltsi %0, -1 \n"
+ " l.bf 1b \n"
+ " l.addi %0, %0, 1 \n"
+ " l.swa 0(%1), %0 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ : "=&r" (tmp)
+ : "r" (&rw->lock)
+ : "cc", "memory");
+
+ smp_mb();
+}
+
+static inline void arch_read_unlock(arch_rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ smp_mb();
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.addi %0, %0, -1 \n"
+ " l.swa 0(%1), %0 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ : "=&r" (tmp)
+ : "r" (&rw->lock)
+ : "cc", "memory");
+
+}
+
+static inline int arch_read_trylock(arch_rwlock_t *rw)
+{
+ unsigned long contended;
+
+ __asm__ __volatile__(
+ "1: l.lwa %0, 0(%1) \n"
+ " l.sfltsi %0, -1 \n"
+ " l.bf 1f \n"
+ " l.addi %0, %0, 1 \n"
+ " l.swa 0(%1), %0 \n"
+ " l.bnf 1b \n"
+ " l.nop \n"
+ "1: \n"
+ : "=&r" (contended)
+ : "r" (&rw->lock)
+ : "cc", "memory");
+
+ /* If the lock is negative, then it is already held for write. */
+ if (contended < 0x80000000) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* read_can_lock - would read_trylock() succeed? */
+#define arch_read_can_lock(x) (ACCESS_ONCE((x)->lock) < 0x80000000)
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
#endif
diff --git a/arch/openrisc/include/asm/spinlock_types.h b/arch/openrisc/include/asm/spinlock_types.h
new file mode 100644
index 0000000..bc0de48
--- /dev/null
+++ b/arch/openrisc/include/asm/spinlock_types.h
@@ -0,0 +1,28 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+#define TICKET_SHIFT 16
+
+typedef struct {
+ union {
+ u32 slock;
+ struct __raw_tickets {
+ u16 next;
+ u16 owner;
+ } tickets;
+ };
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } }
+
+typedef struct {
+ u32 lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
+
+#endif
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:30 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDho-V3-19@gated-at.bofh.it> |
| In reply to | #1585680 |
On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote: > + __asm__ __volatile__( > + "1: l.lwa %0, 0(%3) \n" > + " l.srli %1, %0, 16 \n" > + " l.andi %2, %0, 0xffff \n" > + " l.sfeq %1, %2 \n" > + " l.bnf 1f \n" > + " l.ori %1, r0, 1 \n" > + " l.add %0, %0, %4 \n" > + " l.swa 0(%3), %0 \n" > + " l.bnf 1b \n" > + " l.ori %1, r0, 0 \n" > + "1: \n" > + : "=&r" (slock), "=&r" (contended), "=&r" (tmp) > + : "r" (&lock->slock), "r" (1 << TICKET_SHIFT) > + : "cc", "memory"); > + __asm__ __volatile__( > + "1: l.lwa %0, 0(%1) \n" > + " l.sfeqi %0, 0 \n" > + " l.bnf 1f \n" > + " l.nop \n" > + " l.swa 0(%1), %2 \n" > + " l.bnf 1b \n" > + " l.nop \n" > + "1: \n" > + : "=&r" (tmp) > + : "r" (&rw->lock), "r" (0x80000000) > + : "cc", "memory"); > + __asm__ __volatile__( > + "1: l.lwa %0, 0(%1) \n" > + " l.sfeqi %0, 0 \n" > + " l.bnf 1f \n" > + " l.nop \n" > + " l.swa 0(%1), %2 \n" > + " l.bnf 1b \n" > + " l.nop \n" > + "1: \n" > + : "=&r" (contended) > + : "r" (&rw->lock), "r" (0x80000000) > + : "cc", "memory"); > + __asm__ __volatile__( > + "1: l.lwa %0, 0(%1) \n" > + " l.sfltsi %0, -1 \n" > + " l.bf 1f \n" > + " l.addi %0, %0, 1 \n" > + " l.swa 0(%1), %0 \n" > + " l.bnf 1b \n" > + " l.nop \n" > + "1: \n" > + : "=&r" (contended) > + : "r" (&rw->lock) > + : "cc", "memory"); More asm with 'duplicate' labels.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:40 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDr4-YS-17@gated-at.bofh.it> |
| In reply to | #1585680 |
On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote: > + lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner); > + return !arch_spin_value_unlocked(ACCESS_ONCE(*lock)); > + struct __raw_tickets tickets = ACCESS_ONCE(lock->tickets); > +#define arch_write_can_lock(x) (ACCESS_ONCE((x)->lock) == 0) > +#define arch_read_can_lock(x) (ACCESS_ONCE((x)->lock) < 0x80000000) Please, no ACCESS_ONCE() in new code, use READ_ONCE() or WRITE_ONCE().
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:40 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDr4-YS-21@gated-at.bofh.it> |
| In reply to | #1585680 |
On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote:
> +static inline int arch_spin_trylock(arch_spinlock_t *lock)
> +{
> + unsigned long contended, tmp;
> + u32 slock;
> +
> + /* contended = (lock->tickets.owner != lock->tickets.next) */
> + __asm__ __volatile__(
> + "1: l.lwa %0, 0(%3) \n"
> + " l.srli %1, %0, 16 \n"
> + " l.andi %2, %0, 0xffff \n"
> + " l.sfeq %1, %2 \n"
> + " l.bnf 1f \n"
> + " l.ori %1, r0, 1 \n"
> + " l.add %0, %0, %4 \n"
> + " l.swa 0(%3), %0 \n"
> + " l.bnf 1b \n"
> + " l.ori %1, r0, 0 \n"
#ifdef CONFIG_SMP
" l.sync \n"
#endif
> + "1: \n"
> + : "=&r" (slock), "=&r" (contended), "=&r" (tmp)
> + : "r" (&lock->slock), "r" (1 << TICKET_SHIFT)
> + : "cc", "memory");
> +
Then s/contended/acquired/, flip the bitset in the asm, and replace the
entire thing below with:
return acquired;
> + if (!contended) {
> + smp_mb();
> + return 1;
> + } else {
> + return 0;
> + }
> +}
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 13:10 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDU6-1tU-5@gated-at.bofh.it> |
| In reply to | #1586090 |
On Wed, Feb 22, 2017 at 12:37:09PM +0100, Peter Zijlstra wrote:
> On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote:
>
>
> > +static inline int arch_spin_trylock(arch_spinlock_t *lock)
> > +{
> > + unsigned long contended, tmp;
> > + u32 slock;
> > +
> > + /* contended = (lock->tickets.owner != lock->tickets.next) */
> > + __asm__ __volatile__(
> > + "1: l.lwa %0, 0(%3) \n"
> > + " l.srli %1, %0, 16 \n"
> > + " l.andi %2, %0, 0xffff \n"
> > + " l.sfeq %1, %2 \n"
> > + " l.bnf 1f \n"
> > + " l.ori %1, r0, 1 \n"
> > + " l.add %0, %0, %4 \n"
> > + " l.swa 0(%3), %0 \n"
> > + " l.bnf 1b \n"
> > + " l.ori %1, r0, 0 \n"
>
> #ifdef CONFIG_SMP
> " l.sync \n"
> #endif
Never mind, this part is silly, your l.swa already implies an l.sync. So
you can completely remove the smp_mb() here.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:40 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDr5-YS-31@gated-at.bofh.it> |
| In reply to | #1585680 |
On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote: > +/* > + * RWLOCKS > + * Any particular reason you're not using qrwlock ? include/asm-generic/qrwlock_types.h include/asm-generic/qrwlock.h kernel/locking/qrwlock.c
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 12:50 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDAK-13e-17@gated-at.bofh.it> |
| In reply to | #1585680 |
On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote:
> +static inline void arch_spin_unlock(arch_spinlock_t *lock)
> +{
> + smp_mb();
> + lock->tickets.owner++;
> +}
This is putting a lot of trust in the compiler, nothing is volatile so
it can do horrible things.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-02-22 13:10 +0100 |
| Subject | Re: [PATCH v3 10/25] openrisc: add spinlock implementation |
| Message-ID | <tdDU6-1tU-13@gated-at.bofh.it> |
| In reply to | #1586100 |
On Wed, Feb 22, 2017 at 12:41:17PM +0100, Peter Zijlstra wrote:
> On Wed, Feb 22, 2017 at 04:11:39AM +0900, Stafford Horne wrote:
> > +static inline void arch_spin_unlock(arch_spinlock_t *lock)
> > +{
> > + smp_mb();
> > + lock->tickets.owner++;
> > +}
>
> This is putting a lot of trust in the compiler, nothing is volatile so
> it can do horrible things.
Also, your architecture manual seems to not explicitly mention how
l.lwa/l.swa interact with overlapping l.sh.
In fact, I can read the text such that its done 'wrong'.
[toc] | [prev] | [next] | [standalone]
| From | Stafford Horne <shorne@gmail.com> |
|---|---|
| Date | 2017-02-21 20:30 +0100 |
| Subject | [PATCH v3 20/25] openrisc: entry: Whitespace and comment cleanups |
| Message-ID | <tdoin-6Y4-39@gated-at.bofh.it> |
| In reply to | #1585645 |
Cleanups to whitespace and add some comments. Reading through the delay slot logic I noticed some things: - Delay slot instructions were not indented - Some comments are not lined up - Use tabs and spaces consistent with other code No functional change Signed-off-by: Stafford Horne <shorne@gmail.com> --- arch/openrisc/kernel/entry.S | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index ba1a361..daae2a4 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -228,7 +228,7 @@ EXCEPTION_ENTRY(_data_page_fault_handler) * DTLB miss handler in the CONFIG_GUARD_PROTECTED_CORE part */ #ifdef CONFIG_OPENRISC_NO_SPR_SR_DSX - l.lwz r6,PT_PC(r3) // address of an offending insn + l.lwz r6,PT_PC(r3) // address of an offending insn l.lwz r6,0(r6) // instruction that caused pf l.srli r6,r6,26 // check opcode for jump insn @@ -244,49 +244,47 @@ EXCEPTION_ENTRY(_data_page_fault_handler) l.bf 8f l.sfeqi r6,0x12 // l.jalr l.bf 8f - - l.nop + l.nop l.j 9f - l.nop -8: + l.nop - l.lwz r6,PT_PC(r3) // address of an offending insn +8: // offending insn is in delay slot + l.lwz r6,PT_PC(r3) // address of an offending insn l.addi r6,r6,4 l.lwz r6,0(r6) // instruction that caused pf l.srli r6,r6,26 // get opcode -9: +9: // offending instruction opcode loaded in r6 #else - l.mfspr r6,r0,SPR_SR // SR -// l.lwz r6,PT_SR(r3) // ESR - l.andi r6,r6,SPR_SR_DSX // check for delay slot exception - l.sfeqi r6,0x1 // exception happened in delay slot - l.bnf 7f - l.lwz r6,PT_PC(r3) // address of an offending insn + l.mfspr r6,r0,SPR_SR // SR + l.andi r6,r6,SPR_SR_DSX // check for delay slot exception + l.sfeqi r6,0x1 // exception happened in delay slot + l.bnf 7f + l.lwz r6,PT_PC(r3) // address of an offending insn - l.addi r6,r6,4 // offending insn is in delay slot + l.addi r6,r6,4 // offending insn is in delay slot 7: l.lwz r6,0(r6) // instruction that caused pf l.srli r6,r6,26 // check opcode for write access #endif - l.sfgeui r6,0x33 // check opcode for write access + l.sfgeui r6,0x33 // check opcode for write access l.bnf 1f l.sfleui r6,0x37 l.bnf 1f l.ori r6,r0,0x1 // write access l.j 2f - l.nop + l.nop 1: l.ori r6,r0,0x0 // !write access 2: /* call fault.c handler in or32/mm/fault.c */ l.jal do_page_fault - l.nop + l.nop l.j _ret_from_exception - l.nop + l.nop /* ---[ 0x400: Insn Page Fault exception ]------------------------------- */ EXCEPTION_ENTRY(_itlb_miss_page_fault_handler) @@ -306,9 +304,9 @@ EXCEPTION_ENTRY(_insn_page_fault_handler) /* call fault.c handler in or32/mm/fault.c */ l.jal do_page_fault - l.nop + l.nop l.j _ret_from_exception - l.nop + l.nop /* ---[ 0x500: Timer exception ]----------------------------------------- */ -- 2.9.3
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web