From: Boqun Feng <boqun.feng@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: torvalds@linux-foundation.org, corbet@lwn.net, will@kernel.org,
mark.rutland@arm.com, catalin.marinas@arm.com, dennis@kernel.org,
tj@kernel.org, cl@linux.com, hca@linux.ibm.com,
gor@linux.ibm.com, agordeev@linux.ibm.com,
borntraeger@linux.ibm.com, svens@linux.ibm.com,
Herbert Xu <herbert@gondor.apana.org.au>,
davem@davemloft.net, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, joro@8bytes.org, suravee.suthikulpanit@amd.com,
robin.murphy@arm.com, dwmw2@infradead.org,
baolu.lu@linux.intel.com, Arnd Bergmann <arnd@arndb.de>,
penberg@kernel.org, rientjes@google.com, iamjoonsoo.kim@lge.com,
Andrew Morton <akpm@linux-foundation.org>,
vbabka@suse.cz, roman.gushchin@linux.dev, 42.hyeyoo@gmail.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, linux-s390@vger.kernel.org,
linux-crypto@vger.kernel.org, iommu@lists.linux.dev,
linux-arch@vger.kernel.org
Subject: Re: [RFC][PATCH 05/12] arch: Introduce arch_{,try_}_cmpxchg128{,_local}()
Date: Wed, 21 Dec 2022 17:25:20 -0800 [thread overview]
Message-ID: <Y6OyAL2epKPHj+tr@boqun-archlinux> (raw)
In-Reply-To: <20221219154119.154045458@infradead.org>
On Mon, Dec 19, 2022 at 04:35:30PM +0100, Peter Zijlstra wrote:
> For all architectures that currently support cmpxchg_double()
> implement the cmpxchg128() family of functions that is basically the
> same but with a saner interface.
>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> arch/arm64/include/asm/atomic_ll_sc.h | 38 +++++++++++++++++++++++
> arch/arm64/include/asm/atomic_lse.h | 33 +++++++++++++++++++-
> arch/arm64/include/asm/cmpxchg.h | 26 ++++++++++++++++
> arch/s390/include/asm/cmpxchg.h | 33 ++++++++++++++++++++
> arch/x86/include/asm/cmpxchg_32.h | 3 +
> arch/x86/include/asm/cmpxchg_64.h | 55 +++++++++++++++++++++++++++++++++-
> 6 files changed, 185 insertions(+), 3 deletions(-)
>
> --- a/arch/arm64/include/asm/atomic_ll_sc.h
> +++ b/arch/arm64/include/asm/atomic_ll_sc.h
> @@ -326,6 +326,44 @@ __CMPXCHG_DBL( , , , )
> __CMPXCHG_DBL(_mb, dmb ish, l, "memory")
>
> #undef __CMPXCHG_DBL
> +
> +union __u128_halves {
> + u128 full;
> + struct {
> + u64 low, high;
> + };
> +};
> +
> +#define __CMPXCHG128(name, mb, rel, cl) \
> +static __always_inline u128 \
> +__ll_sc__cmpxchg128##name(volatile u128 *ptr, u128 old, u128 new) \
> +{ \
> + union __u128_halves r, o = { .full = (old) }, \
> + n = { .full = (new) }; \
> + \
> + asm volatile("// __cmpxchg128" #name "\n" \
> + " prfm pstl1strm, %2\n" \
> + "1: ldxp %0, %1, %2\n" \
> + " eor %3, %0, %3\n" \
> + " eor %4, %1, %4\n" \
> + " orr %3, %4, %3\n" \
> + " cbnz %3, 2f\n" \
> + " st" #rel "xp %w3, %5, %6, %2\n" \
> + " cbnz %w3, 1b\n" \
> + " " #mb "\n" \
> + "2:" \
> + : "=&r" (r.low), "=&r" (r.high), "+Q" (*(unsigned long *)ptr) \
> + : "r" (o.low), "r" (o.high), "r" (n.low), "r" (n.high) \
> + : cl); \
> + \
> + return r.full; \
> +}
> +
> +__CMPXCHG128( , , , )
> +__CMPXCHG128(_mb, dmb ish, l, "memory")
> +
> +#undef __CMPXCHG128
> +
> #undef K
>
> #endif /* __ASM_ATOMIC_LL_SC_H */
> --- a/arch/arm64/include/asm/atomic_lse.h
> +++ b/arch/arm64/include/asm/atomic_lse.h
> @@ -151,7 +151,7 @@ __lse_atomic64_fetch_##op##name(s64 i, a
> " " #asm_op #mb " %[i], %[old], %[v]" \
> : [v] "+Q" (v->counter), \
> [old] "=r" (old) \
> - : [i] "r" (i) \
> + : [i] "r" (i) \
> : cl); \
> \
> return old; \
> @@ -324,4 +324,35 @@ __CMPXCHG_DBL(_mb, al, "memory")
>
> #undef __CMPXCHG_DBL
>
> +#define __CMPXCHG128(name, mb, cl...) \
> +static __always_inline u128 \
> +__lse__cmpxchg128##name(volatile u128 *ptr, u128 old, u128 new) \
> +{ \
> + union __u128_halves r, o = { .full = (old) }, \
> + n = { .full = (new) }; \
> + register unsigned long x0 asm ("x0") = o.low; \
> + register unsigned long x1 asm ("x1") = o.high; \
> + register unsigned long x2 asm ("x2") = n.low; \
> + register unsigned long x3 asm ("x3") = n.high; \
> + register unsigned long x4 asm ("x4") = (unsigned long)ptr; \
> + \
> + asm volatile( \
> + __LSE_PREAMBLE \
> + " casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
> + : [old1] "+&r" (x0), [old2] "+&r" (x1), \
> + [v] "+Q" (*(unsigned long *)ptr) \
> + : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
Issue #1: the line below can be removed, otherwise..
> + [oldval1] "r" (r.low), [oldval2] "r" (r.high) \
warning:
./arch/arm64/include/asm/atomic_lse.h: In function '__lse__cmpxchg128_mb':
./arch/arm64/include/asm/atomic_lse.h:309:27: warning: 'r.<U97b8>.low' is used uninitialized [-Wuninitialized]
309 | [oldval1] "r" (r.low), [oldval2] "r" (r.high)
> + : cl); \
> + \
> + r.low = x0; r.high = x1; \
> + \
> + return r.full; \
> +}
> +
> +__CMPXCHG128( , )
> +__CMPXCHG128(_mb, al, "memory")
> +
> +#undef __CMPXCHG128
> +
> #endif /* __ASM_ATOMIC_LSE_H */
> --- a/arch/arm64/include/asm/cmpxchg.h
> +++ b/arch/arm64/include/asm/cmpxchg.h
> @@ -147,6 +147,19 @@ __CMPXCHG_DBL(_mb)
>
> #undef __CMPXCHG_DBL
>
> +#define __CMPXCHG128(name) \
> +static inline long __cmpxchg128##name(volatile u128 *ptr, \
Issue #2: this should be
static inline u128 __cmpxchg128##name(..)
because cmpxchg* needs to return the old value.
Regards,
Boqun
> + u128 old, u128 new) \
> +{ \
> + return __lse_ll_sc_body(_cmpxchg128##name, \
> + ptr, old, new); \
> +}
> +
> +__CMPXCHG128( )
> +__CMPXCHG128(_mb)
> +
> +#undef __CMPXCHG128
> +
> #define __CMPXCHG_GEN(sfx) \
> static __always_inline unsigned long __cmpxchg##sfx(volatile void *ptr, \
> unsigned long old, \
> @@ -229,6 +242,19 @@ __CMPXCHG_GEN(_mb)
> __ret; \
> })
>
> +/* cmpxchg128 */
> +#define system_has_cmpxchg128() 1
> +
> +#define arch_cmpxchg128(ptr, o, n) \
> +({ \
> + __cmpxchg128_mb((ptr), (o), (n)); \
> +})
> +
> +#define arch_cmpxchg128_local(ptr, o, n) \
> +({ \
> + __cmpxchg128((ptr), (o), (n)); \
> +})
> +
> #define __CMPWAIT_CASE(w, sfx, sz) \
> static inline void __cmpwait_case_##sz(volatile void *ptr, \
> unsigned long val) \
> --- a/arch/s390/include/asm/cmpxchg.h
> +++ b/arch/s390/include/asm/cmpxchg.h
> @@ -201,4 +201,37 @@ static __always_inline int __cmpxchg_dou
> (unsigned long)(n1), (unsigned long)(n2)); \
> })
>
> +#define system_has_cmpxchg128() 1
> +
> +static __always_inline u128 arch_cmpxchg128(volatile u128 *ptr, u128 old, u128 new)
> +{
> + asm volatile(
> + " cdsg %[old],%[new],%[ptr]\n"
> + : [old] "+&d" (old)
> + : [new] "d" (new),
> + [ptr] "QS" (*(unsigned long *)ptr)
> + : "memory", "cc");
> + return old;
> +}
> +
> +static __always_inline bool arch_try_cmpxchg128(volatile u128 *ptr, u128 *oldp, u128 new)
> +{
> + u128 old = *oldp;
> + int cc;
> +
> + asm volatile(
> + " cdsg %[old],%[new],%[ptr]\n"
> + " ipm %[cc]\n"
> + " srl %[cc],28\n"
> + : [cc] "=&d" (cc), [old] "+&d" (old)
> + : [new] "d" (new),
> + [ptr] "QS" (*(unsigned long *)ptr)
> + : "memory", "cc");
> +
> + if (unlikely(!cc))
> + *oldp = old;
> +
> + return likely(cc);
> +}
> +
> #endif /* __ASM_CMPXCHG_H */
> --- a/arch/x86/include/asm/cmpxchg_32.h
> +++ b/arch/x86/include/asm/cmpxchg_32.h
> @@ -103,6 +103,7 @@ static inline bool __try_cmpxchg64(volat
>
> #endif
>
> -#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8)
> +#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8)
> +#define system_has_cmpxchg64() boot_cpu_has(X86_FEATURE_CX8)
>
> #endif /* _ASM_X86_CMPXCHG_32_H */
> --- a/arch/x86/include/asm/cmpxchg_64.h
> +++ b/arch/x86/include/asm/cmpxchg_64.h
> @@ -20,6 +20,59 @@
> arch_try_cmpxchg((ptr), (po), (n)); \
> })
>
> -#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16)
> +union __u128_halves {
> + u128 full;
> + struct {
> + u64 low, high;
> + };
> +};
> +
> +static __always_inline u128 arch_cmpxchg128(volatile u128 *ptr, u128 old, u128 new)
> +{
> + union __u128_halves o = { .full = old, }, n = { .full = new, };
> +
> + asm volatile(LOCK_PREFIX "cmpxchg16b %[ptr]"
> + : [ptr] "+m" (*ptr),
> + "+a" (o.low), "+d" (o.high)
> + : "b" (n.low), "c" (n.high)
> + : "memory");
> +
> + return o.full;
> +}
> +
> +static __always_inline u128 arch_cmpxchg128_local(volatile u128 *ptr, u128 old, u128 new)
> +{
> + union __u128_halves o = { .full = old, }, n = { .full = new, };
> +
> + asm volatile("cmpxchg16b %[ptr]"
> + : [ptr] "+m" (*ptr),
> + "+a" (o.low), "+d" (o.high)
> + : "b" (n.low), "c" (n.high)
> + : "memory");
> +
> + return o.full;
> +}
> +
> +static __always_inline bool arch_try_cmpxchg128(volatile u128 *ptr, u128 *old, u128 new)
> +{
> + union __u128_halves o = { .full = *old, }, n = { .full = new, };
> + bool ret;
> +
> + asm volatile(LOCK_PREFIX "cmpxchg16b %[ptr]"
> + CC_SET(e)
> + : CC_OUT(e) (ret),
> + [ptr] "+m" (*ptr),
> + "+a" (o.low), "+d" (o.high)
> + : "b" (n.low), "c" (n.high)
> + : "memory");
> +
> + if (unlikely(!ret))
> + *old = o.full;
> +
> + return likely(ret);
> +}
> +
> +#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16)
> +#define system_has_cmpxchg128() boot_cpu_has(X86_FEATURE_CX16)
>
> #endif /* _ASM_X86_CMPXCHG_64_H */
>
>
next prev parent reply other threads:[~2022-12-22 1:25 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-19 15:35 [RFC][PATCH 00/12] Introduce cmpxchg128() -- aka. the demise of cmpxchg_double() Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 01/12] crypto: Remove u128 usage Peter Zijlstra
2022-12-19 15:56 ` Jason A. Donenfeld
2022-12-19 17:00 ` Peter Zijlstra
2022-12-19 17:03 ` Jason A. Donenfeld
2022-12-20 3:50 ` Herbert Xu
2022-12-20 4:11 ` H. Peter Anvin
2022-12-20 4:15 ` Herbert Xu
2022-12-19 15:35 ` [RFC][PATCH 02/12] crypto/ghash-clmulni: Use (struct) be128 Peter Zijlstra
2022-12-20 5:45 ` Eric Biggers
2022-12-19 15:35 ` [RFC][PATCH 03/12] cyrpto/b128ops: Remove struct u128 Peter Zijlstra
2022-12-20 5:52 ` Eric Biggers
2022-12-19 15:35 ` [RFC][PATCH 04/12] types: Introduce [us]128 Peter Zijlstra
2022-12-29 8:30 ` Pavel Machek
2022-12-19 15:35 ` [RFC][PATCH 05/12] arch: Introduce arch_{,try_}_cmpxchg128{,_local}() Peter Zijlstra
2022-12-19 20:07 ` Boqun Feng
2022-12-20 11:08 ` Peter Zijlstra
2022-12-20 14:31 ` Linus Torvalds
2022-12-20 15:09 ` Peter Zijlstra
2023-01-03 13:25 ` Mark Rutland
2023-01-03 14:03 ` Mark Rutland
2023-01-03 16:19 ` Mark Rutland
2023-01-03 16:50 ` Arnd Bergmann
2023-01-04 11:36 ` Mark Rutland
2023-01-04 13:55 ` Mark Rutland
2022-12-22 1:25 ` Boqun Feng [this message]
2022-12-22 13:16 ` Peter Zijlstra
2023-01-03 17:12 ` Heiko Carstens
2023-01-09 18:50 ` Mark Rutland
2023-01-12 10:35 ` Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 06/12] instrumentation: Wire up cmpxchg128() Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 07/12] percpu: Wire up cmpxchg128 Peter Zijlstra
2022-12-29 13:36 ` Arnd Bergmann
2023-01-04 12:09 ` Heiko Carstens
2023-01-09 16:29 ` Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 08/12] s390: Replace cmpxchg_double() with cmpxchg128() Peter Zijlstra
2023-01-10 7:23 ` Heiko Carstens
2023-01-10 8:32 ` Peter Zijlstra
2023-01-10 11:27 ` Mark Rutland
2023-01-10 11:46 ` Heiko Carstens
2023-01-12 11:12 ` Alexander Gordeev
2022-12-19 15:35 ` [RFC][PATCH 09/12] x86,amd_iommu: Replace cmpxchg_double() Peter Zijlstra
2022-12-19 16:47 ` Niklas Schnelle
2022-12-28 8:40 ` Vasant Hegde
2022-12-19 15:35 ` [RFC][PATCH 10/12] x86,intel_iommu: " Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 11/12] slub: " Peter Zijlstra
2023-01-03 15:58 ` Vlastimil Babka
2023-01-03 17:16 ` Heiko Carstens
2023-01-03 19:08 ` Linus Torvalds
2023-01-04 12:07 ` Heiko Carstens
2023-01-09 16:28 ` Peter Zijlstra
2023-01-09 22:02 ` Linus Torvalds
2023-01-09 22:22 ` H. Peter Anvin
2023-01-10 2:09 ` H. Peter Anvin
2023-01-10 10:28 ` Peter Zijlstra
2022-12-19 15:35 ` [RFC][PATCH 12/12] arch: Remove cmpxchg_double Peter Zijlstra
2022-12-22 1:21 ` [RFC][PATCH 00/12] Introduce cmpxchg128() -- aka. the demise of cmpxchg_double() Boqun Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y6OyAL2epKPHj+tr@boqun-archlinux \
--to=boqun.feng@gmail.com \
--cc=42.hyeyoo@gmail.com \
--cc=agordeev@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=baolu.lu@linux.intel.com \
--cc=borntraeger@linux.ibm.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=cl@linux.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=dennis@kernel.org \
--cc=dwmw2@infradead.org \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=herbert@gondor.apana.org.au \
--cc=hpa@zytor.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-s390@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=penberg@kernel.org \
--cc=peterz@infradead.org \
--cc=rientjes@google.com \
--cc=robin.murphy@arm.com \
--cc=roman.gushchin@linux.dev \
--cc=suravee.suthikulpanit@amd.com \
--cc=svens@linux.ibm.com \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=vbabka@suse.cz \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.