On Tue, 24 May 2011, Michael Hope wrote:
> On Tue, May 24, 2011 at 10:33 AM, Michael Casadevall
> <mcasadev...@ubuntu.com> wrote:
> > On 05/19/2011 10:56 AM, David Gilbert wrote:
> >> On 19 May 2011 16:49, Ken Werner <k...@linux.vnet.ibm.com> wrote:
> >>> On 05/19/2011 12:40 PM, David Rusling wrote:
> >>>>
> >>>> Is this going to end up in a blueprint? This is the last loose end of
> >>>> SMP / atomic memory operations work and I'd like to see it happen
> >>>
> >>> Hi,
> >>>
> >>> Yep, there is one (kind of a skeleton) in place at:
> >>> https://blueprints.launchpad.net/linaro-toolchain-misc/+spec/64-bit-sync-primitives
> >>
> >> Which I'll be filling out in the next few days.
> >>
> >> Dave
> >
> > Is there a timeline for this feature? It's been requested by members of
> > the ARM Server Club to have this implemented, and its important that
> > this makes it into the Ubuntu 11.10 release.
> > Michael
>
> Hi Michael. The topics for this planning cycle are listed here:
> https://wiki.linaro.org/Cycles/1111/TechnicalTopics/Toolchain
>
> 64 bit sync primitives are medium priority so they will be achieved in
> the next six months.
>
> A draft of what is in whos queue is at:
> https://wiki.linaro.org/Cycles/1111/TechnicalTopics/Toolchain/Planning
>
> The primitives are second in Dave's queue so should be started in the
> next three months.
FWIW, here's what the kernel part might look like, i.e. for
compatibility with pre ARMv6k systems (beware, only compile tested):
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index e8d8856..53830a7 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -383,7 +383,7 @@ ENDPROC(__pabt_svc)
.endm
.macro kuser_cmpxchg_check
-#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
#ifndef CONFIG_MMU
#warning "NPTL on non MMU needs fixing"
#else
@@ -392,7 +392,7 @@ ENDPROC(__pabt_svc)
@ perform a quick test inline since it should be false
@ 99.9999% of the time. The rest is done out of line.
cmp r2, #TASK_SIZE
- blhs kuser_cmpxchg_fixup
+ blhs kuser_cmpxchg64_fixup
#endif
#endif
.endm
@@ -797,6 +797,139 @@ __kuser_helper_start:
/*
* Reference prototype:
*
+ * int __kernel_cmpxchgd64(int64_t *oldval, int64_t *newval, int64_t *ptr)
+ *
+ * Input:
+ *
+ * r0 = pointer to oldval
+ * r1 = pointer to newval
+ * r2 = pointer to target value
+ * lr = return address
+ *
+ * Output:
+ *
+ * r0 = returned value (zero or non-zero)
+ * C flag = set if r0 == 0, clear if r0 != 0
+ *
+ * Clobbered:
+ *
+ * r3, flags
+ *
+ * Definition and user space usage example:
+ *
+ * typedef int (__kernel_cmpxchg64_t)(const int64_t *oldval,
+ * const int64_t *newval,
+ * volatile int64_t *ptr);
+ * #define __kernel_cmpxchg64 (*(__kernel_cmpxchg64_t *)0xffff0f60)
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ * The C flag is also set if *ptr was changed to allow for assembly
+ * optimization in the calling code.
+ *
+ * Notes:
+ *
+ * - This routine already includes memory barriers as needed.
+ *
+ * - Due to the length of some sequences, this spans 2 regular kuser
+ * "slots" so 0xffff0f80 is not used as a valid entry point.
+ */
+
+__kuser_cmpxchg64: @ 0xffff0f60
+
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+
+ /*
+ * Poor you. No fast solution possible...
+ * The kernel itself must perform the operation.
+ * A special ghost syscall is used for that (see traps.c).
+ */
+ stmfd sp!, {r7, lr}
+ ldr r7, 1f @ it's 20 bits
+ swi __ARM_NR_cmpxchg64
+ ldmfd sp!, {r7, pc}
+1: .word __ARM_NR_cmpxchg64
+
+#elif defined(CONFIG_CPU_32v6K)
+
+ stmfd sp!, {r4, r5, r6, r7}
+ ldrd r4, r5, [r0] @ load old val
+ ldrd r6, r7, [r1] @ load new val
+ smp_dmb arm
+1: ldrexd r0, r1, [r2] @ load current val
+ eors r3, r0, r4 @ compare with oldval (1)
+ eoreqs r3, r1, r5 @ compare with oldval (2)
+ strexdeq r3, r6, r7, [r2] @ store newval if eq
+ teqeq r3, #1 @ success?
+ beq 1b @ if no then retry
+ smp_dmb arm
+ rsbs r0, r3, #0 @ set returned val and C flag
+ ldmfd sp!, {r4, r5, r6, r7}
+ usr_ret lr
+
+#elif !defined(CONFIG_SMP)
+
+#ifdef CONFIG_MMU
+
+ /*
+ * The only thing that can break atomicity in this cmpxchg64
+ * implementation is either an IRQ or a data abort exception
+ * causing another process/thread to be scheduled in the middle
+ * of the critical sequence. To prevent this, code is added to
+ * the IRQ and data abort exception handlers to set the pc back
+ * to the beginning of the critical section if it is found to be
+ * within that critical section (see kuser_cmpxchg_fixup64).
+ */
+ stmfd sp!, {r4, r5, r6, lr}
+ ldmia r0, {r4, r5} @ load old val
+ ldmia r1, {r6, lr} @ load new val
+1: ldmia r2, {r0, r1} @ load current val
+ eors r3, r0, r4 @ compare with oldval (1)
+ eoreqs r3, r1, r5 @ compare with oldval (2)
+2: stmeqia r2, {r6, lr} @ store newval if eq
+ rsbs r0, r3, #0 @ set return val and C flag
+ ldmfd sp!, {r4, r5, r6, pc}
+
+ .text
+kuser_cmpxchg64_fixup:
+ @ Called from kuser_cmpxchg_fixup.
+ @ r2 = address of interrupted insn (must be preserved).
+ @ sp = saved regs. r7 and r8 are clobbered.
+ @ 1b = first critical insn, 2b = last critical insn.
+ @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
+ mov r7, #0xffff0fff
+ sub r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64)))
+ subs r8, r2, r7
+ rsbcss r8, r8, #(2b - 1b)
+ strcs r7, [sp, #S_PC]
+#if __LINUX_ARM_ARCH__ < 6
+ b kuser_cmpxchg32_fixup
+#else
+ mov pc, lr
+#endif
+ .previous
+
+#else
+#warning "NPTL on non MMU needs fixing"
+ mov r0, #-1
+ adds r0, r0, #0
+ usr_ret lr
+#endif
+
+#else
+#error "incoherent kernel configuration"
+#endif
+
+ /* pad to next slot */
+ .rept (16 - (. - __kuser_cmpxchg64)/4)
+ .word 0
+ .endr
+
+ .align 5
+
+/*
+ * Reference prototype:
+ *
* void __kernel_memory_barrier(void)
*
* Input:
@@ -921,7 +1054,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
usr_ret lr
.text
-kuser_cmpxchg_fixup:
+kuser_cmpxchg32_fixup:
@ Called from kuser_cmpxchg_check macro.
@ r2 = address of interrupted insn (must be preserved).
@ sp = saved regs. r7 and r8 are clobbered.
_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev