Messages in this thread | | | From | Guo Ren <> | Date | Fri, 4 Aug 2023 13:45:11 -0400 | Subject | Re: [RFC PATCH v3 4/5] riscv/cmpxchg: Implement cmpxchg for variables of size 1 and 2 |
| |
On Fri, Aug 4, 2023 at 4:49 AM Leonardo Bras <leobras@redhat.com> wrote: > > cmpxchg for variables of size 1-byte and 2-bytes is not yet available for > riscv, even though its present in other architectures such as arm64 and > x86. This could lead to not being able to implement some locking mechanisms > or requiring some rework to make it work properly. > > Implement 1-byte and 2-bytes cmpxchg in order to achieve parity with other > architectures. > > Signed-off-by: Leonardo Bras <leobras@redhat.com> > --- > arch/riscv/include/asm/cmpxchg.h | 35 ++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h > index 5a07646fae65..dfb433ac544f 100644 > --- a/arch/riscv/include/asm/cmpxchg.h > +++ b/arch/riscv/include/asm/cmpxchg.h > @@ -72,6 +72,36 @@ > * indicated by comparing RETURN with OLD. > */ > > +#define __arch_cmpxchg_mask(sc_sfx, prepend, append, r, p, o, n) \ > +({ \ > + /* Depends on 2-byte variables being 2-byte aligned */ \ > + ulong __s = ((ulong)(p) & 0x3) * BITS_PER_BYTE; \ > + ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \ > + << __s; \ > + ulong __newx = (ulong)(n) << __s; \ > + ulong __oldx = (ulong)(o) << __s; \ > + ulong __retx; \ > + register unsigned int __rc; \ > + \ > + __asm__ __volatile__ ( \ > + prepend \ > + "0: lr.w %0, %2\n" \ > + " and %0, %0, %z5\n" \ > + " bne %0, %z3, 1f\n" \ bug: - " and %0, %0, %z5\n" \ - " bne %0, %z3, 1f\n" \ + " and %1, %0, %z5\n" \ + " bne %1, %z3, 1f\n" \ Your code breaks the %0.
> + " and %1, %0, %z6\n" \ > + " or %1, %1, %z4\n" \ > + " sc.w" sc_sfx " %1, %1, %2\n" \ > + " bnez %1, 0b\n" \ > + append \ > + "1:\n" \ > + : "=&r" (__retx), "=&r" (__rc), "+A" (*(p)) \ > + : "rJ" ((long)__oldx), "rJ" (__newx), \ > + "rJ" (__mask), "rJ" (~__mask) \ > + : "memory"); \ > + \ > + r = (__typeof__(*(p)))(__retx >> __s); \ > +}) > + > > #define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \ > ({ \ > @@ -98,6 +128,11 @@ > __typeof__(*(ptr)) __ret; \ > \ > switch (sizeof(*__ptr)) { \ > + case 1: \ > + case 2: \ > + __arch_cmpxchg_mask(sc_sfx, prepend, append, \ > + __ret, __ptr, __old, __new); \ > + break; \ > case 4: \ > __arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \ > __ret, __ptr, (long), __old, __new); \ > -- > 2.41.0 >
-- Best Regards Guo Ren
| |