From: Oleksii <oleksii.kurochko@gmail.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: Alistair Francis <alistair.francis@wdc.com>,
Bob Eshleman <bobbyeshleman@gmail.com>,
Connor Davis <connojdavis@gmail.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
George Dunlap <george.dunlap@citrix.com>,
Julien Grall <julien@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>, Wei Liu <wl@xen.org>,
xen-devel@lists.xenproject.org
Subject: Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
Date: Tue, 23 Jan 2024 14:18:50 +0200 [thread overview]
Message-ID: <835c58c1deb89db2fa500bd7cd767facd5b5fb78.camel@gmail.com> (raw)
In-Reply-To: <c5872ae0-a26a-4f51-bad6-08fd0c37d488@suse.com>
On Tue, 2024-01-23 at 11:28 +0100, Jan Beulich wrote:
> On 23.01.2024 11:15, Oleksii wrote:
> > On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory" ); \
> > > > + break; \
> > > > + case 8: \
> > > > + asm volatile( \
> > > > + " amoswap.d %0, %2, %1\n" \
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory" ); \
> > > > + break; \
> > > > + default: \
> > > > + ASSERT_UNREACHABLE(); \
> > >
> > > If at all possible this wants to trigger a build failure, not a
> > > runtime
> > > one.
> > I'll update that with BUILD_BUG_ON(size > 8);
>
> What about size accidentally being e.g. 5? I'm also not sure you'll
> be
> able to use BUILD_BUG_ON() here: That'll depend on what use sites
> there
> are. And if all present ones are okay in this regard, you'd still set
> out a trap for someone else to fall into later. We have a common
> approach for this, which currently is under re-work. See
> https://lists.xen.org/archives/html/xen-devel/2024-01/msg01115.html.
Thanks. I'll use that.
>
> > > > + } \
> > > > + ret__; \
> > > > +})
> > > > +
> > > > +#define xchg_relaxed(ptr, x) \
> > > > +({ \
> > > > + __typeof__(*(ptr)) x_ = (x); \
> > > > + (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_,
> > > > sizeof(*(ptr))); \
> > >
> > > Nit: Stray blank after cast. For readability I'd also suggest to
> > > drop parentheses in cases like the first argument passed to
> > > __xchg_relaxed() here.
> > Thanks. I'll take that into account.
> >
> > >
> > > > +})
> > >
> > > For both: What does "relaxed" describe? I'm asking because it's
> > > not
> > > really clear whether the memory clobbers are actually needed.
> > >
> > > > +#define __xchg_acquire(ptr, new, size) \
> > > > +({ \
> > > > + __typeof__(ptr) ptr__ = (ptr); \
> > > > + __typeof__(new) new__ = (new); \
> > > > + __typeof__(*(ptr)) ret__; \
> > > > + switch (size) \
> > > > + { \
> > > > + case 4: \
> > > > + asm volatile( \
> > > > + " amoswap.w %0, %2, %1\n" \
> > > > + RISCV_ACQUIRE_BARRIER \
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory" ); \
> > > > + break; \
> > > > + case 8: \
> > > > + asm volatile( \
> > > > + " amoswap.d %0, %2, %1\n" \
> > > > + RISCV_ACQUIRE_BARRIER \
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory" ); \
> > > > + break; \
> > > > + default: \
> > > > + ASSERT_UNREACHABLE(); \
> > > > + } \
> > > > + ret__; \
> > > > +})
> > >
> > > If I'm not mistaken this differs from __xchg_relaxed() only in
> > > the
> > > use
> > > of RISCV_ACQUIRE_BARRIER, and ...
> > >
> > > > +#define xchg_acquire(ptr, x) \
> > > > +({ \
> > > > + __typeof__(*(ptr)) x_ = (x); \
> > > > + (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > > +})
> > > > +
> > > > +#define __xchg_release(ptr, new, size) \
> > > > +({ \
> > > > + __typeof__(ptr) ptr__ = (ptr); \
> > > > + __typeof__(new) new__ = (new); \
> > > > + __typeof__(*(ptr)) ret__; \
> > > > + switch (size) \
> > > > + { \
> > > > + case 4: \
> > > > + asm volatile ( \
> > > > + RISCV_RELEASE_BARRIER \
> > > > + " amoswap.w %0, %2, %1\n" \
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory"); \
> > > > + break; \
> > > > + case 8: \
> > > > + asm volatile ( \
> > > > + RISCV_RELEASE_BARRIER \
> > > > + " amoswap.d %0, %2, %1\n" \
> > > > + : "=r" (ret__), "+A" (*ptr__) \
> > > > + : "r" (new__) \
> > > > + : "memory"); \
> > > > + break; \
> > > > + default: \
> > > > + ASSERT_UNREACHABLE(); \
> > > > + } \
> > > > + ret__; \
> > > > +})
> > >
> > > this only in the use of RISCV_RELEASE_BARRIER. If so they likely
> > > want
> > > folding, to limit redundancy and make eventual updating easier.
> > > (Same
> > > for the cmpxchg helper further down, as it seems.)
> > Yes, you are right. The difference is only in RISCV_RELEASE_BARRIER
> > and
> > it is an absence of RISCV_RELEASE_BARRIER is a reason why we have
> > "relaxed" versions.
> >
> > I am not sure that I understand what you mean by folding here. Do
> > you
> > mean that there is no any sense to have to separate macros and it
> > is
> > needed only one with RISCV_RELEASE_BARRIER?
>
> No. You should parameterize the folded common macro for the derived
> macros to simply pass in the barriers needed, with empty macro
> arguments indicating "this barrier not needed".
Now it makes sense to me. Thank you for explanation.
>
> > > > +#define xchg_release(ptr, x) \
> > > > +({ \
> > > > + __typeof__(*(ptr)) x_ = (x); \
> > > > + (__typeof__(*(ptr))) __xchg_release((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > > +})
> > > > +
> > > > +static always_inline uint32_t __xchg_case_4(volatile uint32_t
> > > > *ptr,
> > > > + uint32_t new)
> > > > +{
> > > > + __typeof__(*(ptr)) ret;
> > > > +
> > > > + asm volatile (
> > > > + " amoswap.w.aqrl %0, %2, %1\n"
> > > > + : "=r" (ret), "+A" (*ptr)
> > > > + : "r" (new)
> > > > + : "memory" );
> > > > +
> > > > + return ret;
> > > > +}
> > > > +
> > > > +static always_inline uint64_t __xchg_case_8(volatile uint64_t
> > > > *ptr,
> > > > + uint64_t new)
> > > > +{
> > > > + __typeof__(*(ptr)) ret;
> > > > +
> > > > + asm volatile( \
> > > > + " amoswap.d.aqrl %0, %2, %1\n" \
> > > > + : "=r" (ret), "+A" (*ptr) \
> > > > + : "r" (new) \
> > > > + : "memory" ); \
> > > > +
> > > > + return ret;
> > > > +}
> > > > +
> > > > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > > > uint32_t *ptr,
> > > > + uint32_t
> > > > old,
> > > > + uint32_t
> > > > new);
> > >
> > > Don't you consistently mean uint16_t here (incl the return type)
> > > and
> > > ...
> > >
> > > > +static always_inline unsigned short __cmpxchg_case_1(volatile
> > > > uint32_t *ptr,
> > > > + uint32_t
> > > > old,
> > > > + uint32_t
> > > > new);
> > >
> > > ... uint8_t here?
> > The idea was that we emulate __cmpxchg_case_1 and __cmpxchg_case_2
> > using 4 bytes cmpxchg and __cmpxchg_case_4 expects uint32_t.
>
> I consider this wrong. The functions would better be type-correct.
>
> > > > +static inline unsigned long __xchg(volatile void *ptr,
> > > > unsigned
> > > > long x, int size)
> > > > +{
> > > > + switch (size) {
> > > > + case 1:
> > > > + return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
> > > > + case 2:
> > > > + return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
> > >
> > > How are these going to work? You'll compare against ~0, and if
> > > the
> > > value
> > > in memory isn't ~0, memory won't be updated; you will only
> > > (correctly)
> > > return the value found in memory.
> > >
> > > Or wait - looking at __cmpxchg_case_{1,2}() far further down, you
> > > ignore
> > > "old" there. Which apparently means they'll work for the use
> > > here,
> > > but
> > > not for the use in __cmpxchg().
> > Yes, the trick is that old is ignored and is read in
> > __emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
> > do
> > {
> > read_val =
> > read_func(aligned_ptr);
> > swapped_new = read_val &
> > ~mask;
> > swapped_new |=
> > masked_new;
> > ret = cmpxchg_func(aligned_ptr, read_val,
> > swapped_new);
> > } while ( ret != read_val
> > );
> > read_val it is 'old'.
> >
> > But now I am not 100% sure that it is correct for __cmpxchg...
>
> It just can't be correct - you can't ignore "old" there. I think you
> want simple cmpxchg primitives, which xchg then uses in a loop (while
> cmpxchg uses them plainly).
But xchg doesn't require 'old' value, so it should be ignored in some
way by cmpxchg.
>
> > > > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > > > uint32_t *ptr,
> > > > + uint32_t
> > > > old,
> > > > + uint32_t
> > > > new)
> > > > +{
> > > > + (void) old;
> > > > +
> > > > + if (((unsigned long)ptr & 3) == 3)
> > > > + {
> > > > +#ifdef CONFIG_64BIT
> > > > + return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
> > > > + readq,
> > > > __cmpxchg_case_8,
> > > > 0xffffU);
> > >
> > > What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of
> > > what
> > > the
> > > if() above checks for? Isn't it more reasonable to require
> > > aligned
> > > 16-bit quantities here? Or if mis-aligned addresses are okay, you
> > > could
> > > as well emulate using __cmpxchg_case_4().
> > Yes, it will be more reasonable. I'll use IS_ALIGNED instead.
>
> Not sure I get your use of "instead" here correctly. There's more
> to change here than just the if() condition.
I meant something like:
if ( IS_ALIGNED(ptr, 16) )
__emulate_cmpxchg_case1_2(...);
else
assert_failed("ptr isn't aligned\n");
I have to check if it is necessary to have an mis-aligned address for
CAS intstuctions.
If mis-aligned address is okay then it looks like we can use always
__cmpxchng_case_4 without checking if a ptr is ALIGNED or not. Or I
started to loose something...
~ Oleksii
next prev parent reply other threads:[~2024-01-23 12:19 UTC|newest]
Thread overview: 146+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 01/34] xen/riscv: disable unnecessary configs Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 02/34] xen/riscv: use some asm-generic headers Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V Oleksii Kurochko
2024-01-04 11:01 ` Jan Beulich
2024-01-08 14:46 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 04/34] xen/riscv: introduce cpufeature.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h Oleksii Kurochko
2024-01-11 15:57 ` Jan Beulich
2024-01-15 9:26 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h Oleksii Kurochko
2024-01-04 11:04 ` Jan Beulich
2024-01-08 14:47 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
2024-01-04 11:06 ` Jan Beulich
2024-01-04 11:13 ` Andrew Cooper
2024-01-04 12:03 ` Jan Beulich
2024-01-08 14:58 ` Oleksii
2024-01-05 19:02 ` Shawn Anastasio
2023-12-22 15:12 ` [PATCH v3 08/34] xen/riscv: introduce setup.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 09/34] xen/riscv: introduce system.h Oleksii Kurochko
2024-01-11 16:00 ` Jan Beulich
2024-01-15 9:28 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
2024-01-15 16:44 ` Jan Beulich
2024-01-16 13:06 ` Oleksii
2024-01-16 13:24 ` Jan Beulich
2024-01-17 11:13 ` Oleksii
2024-01-17 11:17 ` Jan Beulich
2024-01-17 11:37 ` Oleksii
2024-01-17 13:42 ` Jan Beulich
2024-01-18 9:43 ` Oleksii
2024-01-18 11:01 ` Jan Beulich
2024-01-19 9:16 ` Oleksii
2024-01-19 9:20 ` Jan Beulich
2024-01-18 11:03 ` Jan Beulich
2024-01-19 9:09 ` Oleksii
2024-01-19 9:14 ` Jan Beulich
2024-01-19 9:30 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 11/34] xen/riscv: introduce flushtlb.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 12/34] xen/riscv: introduce smp.h Oleksii Kurochko
2024-01-11 16:36 ` Jan Beulich
2024-01-15 9:35 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h Oleksii Kurochko
2024-01-22 16:27 ` Jan Beulich
2024-01-23 10:15 ` Oleksii
2024-01-23 10:28 ` Jan Beulich
2024-01-23 12:18 ` Oleksii [this message]
2024-01-23 13:27 ` Jan Beulich
2024-01-24 9:15 ` Oleksii
2024-01-30 14:57 ` Oleksii
2024-01-30 15:05 ` Jan Beulich
2024-01-30 15:16 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 14/34] xen/riscv: introduce io.h Oleksii Kurochko
2024-01-15 16:57 ` Jan Beulich
2024-01-16 15:20 ` Oleksii
2024-01-16 16:09 ` Jan Beulich
2024-01-31 17:30 ` Oleksii
2023-12-22 15:12 ` [PATCH v3 15/34] xen/riscv: introduce atomic.h Oleksii Kurochko
2024-01-22 16:56 ` Jan Beulich
2024-01-23 10:21 ` Oleksii
2024-01-23 10:30 ` Jan Beulich
2024-01-23 12:24 ` Oleksii
2024-01-23 13:30 ` Jan Beulich
2024-01-24 9:23 ` Oleksii
2024-01-24 11:19 ` Jan Beulich
2024-01-24 14:56 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 16/34] xen/lib: introduce generic find next bit operations Oleksii Kurochko
2024-01-23 11:14 ` Jan Beulich
2024-01-23 12:34 ` Oleksii
2024-01-23 13:37 ` Jan Beulich
2024-01-24 9:34 ` Oleksii
2024-01-24 11:24 ` Jan Beulich
2024-01-24 15:04 ` Oleksii
2024-01-24 15:32 ` Jan Beulich
2024-01-26 9:44 ` Oleksii
2024-01-26 9:48 ` Jan Beulich
2024-01-26 9:56 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 17/34] xen/riscv: add compilation of generic find-next-bit.c Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 18/34] xen/riscv: introduce domain.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 19/34] xen/riscv: introduce guest_access.h Oleksii Kurochko
2024-01-23 11:16 ` Jan Beulich
2023-12-22 15:13 ` [PATCH v3 20/34] xen/riscv: introduce irq.h Oleksii Kurochko
2024-01-23 11:18 ` Jan Beulich
2024-01-23 12:25 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
2024-01-11 23:11 ` Shawn Anastasio
2024-01-15 9:37 ` Oleksii
2024-01-12 10:39 ` Julien Grall
2024-01-12 11:06 ` Jan Beulich
2024-01-12 11:09 ` Julien Grall
2024-01-15 10:35 ` Oleksii
2024-01-15 11:01 ` Jan Beulich
2024-01-16 9:44 ` Oleksii
2024-01-16 17:12 ` Julien Grall
2024-01-17 9:32 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 22/34] xen/riscv: introduce regs.h Oleksii Kurochko
2024-01-15 17:00 ` Jan Beulich
2024-01-16 9:46 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 23/34] xen/riscv: introduce time.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 24/34] xen/riscv: introduce event.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 25/34] xen/riscv: introduce monitor.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 26/34] xen/riscv: add definition of __read_mostly Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 27/34] xen/riscv: define an address of frame table Oleksii Kurochko
2024-01-23 11:32 ` Jan Beulich
2024-01-23 16:50 ` Oleksii
2024-01-24 8:07 ` Jan Beulich
2024-01-24 10:01 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 28/34] xen/riscv: add required things to current.h Oleksii Kurochko
2024-01-23 11:35 ` Jan Beulich
2024-01-23 16:52 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen Oleksii Kurochko
2024-01-23 11:36 ` Jan Beulich
2024-01-23 16:54 ` Oleksii
2024-01-24 8:09 ` Jan Beulich
2024-01-24 10:02 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h " Oleksii Kurochko
2024-01-23 11:39 ` Jan Beulich
2024-01-23 17:08 ` Oleksii
2024-01-24 8:19 ` Jan Beulich
2024-01-24 10:12 ` Oleksii
2024-01-24 11:27 ` Jan Beulich
2024-01-24 15:33 ` Oleksii
2024-01-24 15:38 ` Jan Beulich
2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
2023-12-22 16:32 ` Oleksii
2023-12-22 18:16 ` Oleksii
2024-01-11 16:43 ` Jan Beulich
2024-01-15 10:36 ` Oleksii
2024-01-23 13:03 ` Jan Beulich
2024-01-23 17:27 ` Oleksii
2024-01-24 8:23 ` Jan Beulich
2024-02-02 17:30 ` Oleksii
2024-02-05 7:46 ` Jan Beulich
2024-02-05 12:49 ` Oleksii
2024-02-05 14:05 ` Jan Beulich
2024-02-05 14:40 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs " Oleksii Kurochko
2024-01-23 13:20 ` Jan Beulich
2024-01-23 17:31 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 33/34] xen/riscv: enable full Xen build Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64 Oleksii Kurochko
2024-01-23 11:22 ` Jan Beulich
2024-01-23 14:49 ` Oleksii
2024-01-23 17:05 ` Jan Beulich
2024-01-23 17:34 ` Oleksii
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=835c58c1deb89db2fa500bd7cd767facd5b5fb78.camel@gmail.com \
--to=oleksii.kurochko@gmail.com \
--cc=alistair.francis@wdc.com \
--cc=andrew.cooper3@citrix.com \
--cc=bobbyeshleman@gmail.com \
--cc=connojdavis@gmail.com \
--cc=george.dunlap@citrix.com \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=sstabellini@kernel.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.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.