Date: Wed, 16 May 2018 21:04:20 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r333687 - stable/11/sys/arm/include Message-ID: <201805162104.w4GL4Kmw029010@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed May 16 21:04:19 2018 New Revision: 333687 URL: https://svnweb.freebsd.org/changeset/base/333687 Log: MFC 332891,332892: Fixes for atomic_*cmpset() on arm. 332891: Fix some harmless type mismatches in the ARM atomic_cmpset implementations. The return value of atomic_cmpset() and atomic_fcmpset() is an int (which is really a bool) that has the values 0 or 1. Some of the inlines were using the type being operated on (e.g. uint32_t) as either the return type of the function, or the type of a local 'ret' variable used to hold the return value. Fix all of these to just use plain 'int'. Due to C promotion rules and the fact that the value can only be 0 or 1, these should all be harmless. 332892: Implement 32-bit atomic_fcmpset() in userland for armv4/v5. - Add an implementation of atomic_fcmpset_32() using RAS for armv4/v5. This fixes recent world breakage due to use of atomic_fcmpset() in userland. - While here, be more careful to not expose wrapper macros for 64-bit atomic_*cmpset to userland for armv4/v5 as only 32-bit cmpset is implemented. This has been reviewed, but not runtime-tested, but should fix the arm.arm and arm.armeb worlds that have been broken for a while. Approved by: re (kib) Modified: stable/11/sys/arm/include/atomic-v4.h stable/11/sys/arm/include/atomic-v6.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/arm/include/atomic-v4.h ============================================================================== --- stable/11/sys/arm/include/atomic-v4.h Wed May 16 21:03:22 2018 (r333686) +++ stable/11/sys/arm/include/atomic-v4.h Wed May 16 21:04:19 2018 (r333687) @@ -115,7 +115,7 @@ atomic_clear_64(volatile uint64_t *address, uint64_t c static __inline int atomic_fcmpset_32(volatile u_int32_t *p, volatile u_int32_t *cmpval, volatile u_int32_t newval) { - u_int32_t ret; + int ret; __with_interrupts_disabled( { @@ -134,7 +134,7 @@ atomic_fcmpset_32(volatile u_int32_t *p, volatile u_in static __inline int atomic_fcmpset_64(volatile u_int64_t *p, volatile u_int64_t *cmpval, volatile u_int64_t newval) { - u_int64_t ret; + int ret; __with_interrupts_disabled( { @@ -149,7 +149,7 @@ atomic_fcmpset_64(volatile u_int64_t *p, volatile u_in return (ret); } -static __inline u_int32_t +static __inline int atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval) { int ret; @@ -166,7 +166,7 @@ atomic_cmpset_32(volatile u_int32_t *p, volatile u_int return (ret); } -static __inline u_int64_t +static __inline int atomic_cmpset_64(volatile u_int64_t *p, volatile u_int64_t cmpval, volatile u_int64_t newval) { int ret; @@ -296,7 +296,7 @@ atomic_clear_32(volatile uint32_t *address, uint32_t c } -static __inline u_int32_t +static __inline int atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval) { int done, ras_start = ARM_RAS_START; @@ -321,6 +321,33 @@ atomic_cmpset_32(volatile u_int32_t *p, volatile u_int return (done); } +static __inline int +atomic_fcmpset_32(volatile u_int32_t *p, volatile u_int32_t *cmpval, volatile u_int32_t newval) +{ + int done, oldval, ras_start = ARM_RAS_START; + + __asm __volatile("1:\n" + "adr %1, 1b\n" + "str %1, [%0]\n" + "adr %1, 2f\n" + "str %1, [%0, #4]\n" + "ldr %1, [%2]\n" + "ldr %5, [%3]\n" + "cmp %1, %5\n" + "streq %4, [%2]\n" + "2:\n" + "mov %5, #0\n" + "str %5, [%0]\n" + "mov %5, #0xffffffff\n" + "str %5, [%0, #4]\n" + "strne %1, [%3]\n" + "moveq %1, #1\n" + "movne %1, #0\n" + : "+r" (ras_start), "=r" (done) ,"+r" (p) + , "+r" (cmpval), "+r" (newval), "+r" (oldval) : : "cc", "memory"); + return (done); +} + static __inline uint32_t atomic_fetchadd_32(volatile uint32_t *p, uint32_t v) { @@ -409,14 +436,18 @@ atomic_swap_32(volatile u_int32_t *p, u_int32_t v) #define atomic_fcmpset_rel_32 atomic_fcmpset_32 #define atomic_fcmpset_acq_32 atomic_fcmpset_32 +#ifdef _KERNEL #define atomic_fcmpset_rel_64 atomic_fcmpset_64 #define atomic_fcmpset_acq_64 atomic_fcmpset_64 +#endif #define atomic_fcmpset_acq_long atomic_fcmpset_long #define atomic_fcmpset_rel_long atomic_fcmpset_long #define atomic_cmpset_rel_32 atomic_cmpset_32 #define atomic_cmpset_acq_32 atomic_cmpset_32 +#ifdef _KERNEL #define atomic_cmpset_rel_64 atomic_cmpset_64 #define atomic_cmpset_acq_64 atomic_cmpset_64 +#endif #define atomic_set_rel_32 atomic_set_32 #define atomic_set_acq_32 atomic_set_32 #define atomic_clear_rel_32 atomic_clear_32 @@ -463,8 +494,6 @@ atomic_cmpset_long(volatile u_long *dst, u_long old, u return (atomic_cmpset_32((volatile uint32_t *)dst, old, newe)); } -#ifdef _KERNEL -/* atomic_fcmpset_32 is only defined for the kernel */ static __inline u_long atomic_fcmpset_long(volatile u_long *dst, u_long *old, u_long newe) { @@ -472,7 +501,6 @@ atomic_fcmpset_long(volatile u_long *dst, u_long *old, return (atomic_fcmpset_32((volatile uint32_t *)dst, (uint32_t *)old, newe)); } -#endif static __inline u_long atomic_fetchadd_long(volatile u_long *p, u_long v) Modified: stable/11/sys/arm/include/atomic-v6.h ============================================================================== --- stable/11/sys/arm/include/atomic-v6.h Wed May 16 21:03:22 2018 (r333686) +++ stable/11/sys/arm/include/atomic-v6.h Wed May 16 21:04:19 2018 (r333687) @@ -209,7 +209,7 @@ atomic_fcmpset_32(volatile uint32_t *p, uint32_t *cmpv return (!ret); } -static __inline uint64_t +static __inline int atomic_fcmpset_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) { uint64_t tmp; @@ -235,7 +235,7 @@ atomic_fcmpset_64(volatile uint64_t *p, uint64_t *cmpv return (!ret); } -static __inline u_long +static __inline int atomic_fcmpset_long(volatile u_long *p, u_long *cmpval, u_long newval) { @@ -243,38 +243,38 @@ atomic_fcmpset_long(volatile u_long *p, u_long *cmpval (uint32_t *)cmpval, newval)); } -static __inline uint64_t +static __inline int atomic_fcmpset_acq_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) { - uint64_t ret; + int ret; ret = atomic_fcmpset_64(p, cmpval, newval); dmb(); return (ret); } -static __inline u_long +static __inline int atomic_fcmpset_acq_long(volatile u_long *p, u_long *cmpval, u_long newval) { - u_long ret; + int ret; ret = atomic_fcmpset_long(p, cmpval, newval); dmb(); return (ret); } -static __inline uint32_t +static __inline int atomic_fcmpset_acq_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval) { - uint32_t ret; + int ret; ret = atomic_fcmpset_32(p, cmpval, newval); dmb(); return (ret); } -static __inline uint32_t +static __inline int atomic_fcmpset_rel_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval) { @@ -282,7 +282,7 @@ atomic_fcmpset_rel_32(volatile uint32_t *p, uint32_t * return (atomic_fcmpset_32(p, cmpval, newval)); } -static __inline uint64_t +static __inline int atomic_fcmpset_rel_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) { @@ -290,7 +290,7 @@ atomic_fcmpset_rel_64(volatile uint64_t *p, uint64_t * return (atomic_fcmpset_64(p, cmpval, newval)); } -static __inline u_long +static __inline int atomic_fcmpset_rel_long(volatile u_long *p, u_long *cmpval, u_long newval) { @@ -298,10 +298,10 @@ atomic_fcmpset_rel_long(volatile u_long *p, u_long *cm return (atomic_fcmpset_long(p, cmpval, newval)); } -static __inline uint32_t +static __inline int atomic_cmpset_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval) { - uint32_t ret; + int ret; __asm __volatile( "1: ldrex %0, [%1] \n" @@ -349,44 +349,44 @@ atomic_cmpset_64(volatile uint64_t *p, uint64_t cmpval return (ret); } -static __inline u_long +static __inline int atomic_cmpset_long(volatile u_long *p, u_long cmpval, u_long newval) { return (atomic_cmpset_32((volatile uint32_t *)p, cmpval, newval)); } -static __inline uint32_t +static __inline int atomic_cmpset_acq_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval) { - uint32_t ret; + int ret; ret = atomic_cmpset_32(p, cmpval, newval); dmb(); return (ret); } -static __inline uint64_t +static __inline int atomic_cmpset_acq_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval) { - uint64_t ret; + int ret; ret = atomic_cmpset_64(p, cmpval, newval); dmb(); return (ret); } -static __inline u_long +static __inline int atomic_cmpset_acq_long(volatile u_long *p, u_long cmpval, u_long newval) { - u_long ret; + int ret; ret = atomic_cmpset_long(p, cmpval, newval); dmb(); return (ret); } -static __inline uint32_t +static __inline int atomic_cmpset_rel_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval) { @@ -394,7 +394,7 @@ atomic_cmpset_rel_32(volatile uint32_t *p, uint32_t cm return (atomic_cmpset_32(p, cmpval, newval)); } -static __inline uint64_t +static __inline int atomic_cmpset_rel_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval) { @@ -402,7 +402,7 @@ atomic_cmpset_rel_64(volatile uint64_t *p, uint64_t cm return (atomic_cmpset_64(p, cmpval, newval)); } -static __inline u_long +static __inline int atomic_cmpset_rel_long(volatile u_long *p, u_long cmpval, u_long newval) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805162104.w4GL4Kmw029010>