locking/arch: Wire up local_try_cmpxchg()
authorUros Bizjak <ubizjak@gmail.com>
Wed, 5 Apr 2023 14:17:08 +0000 (16:17 +0200)
committerIngo Molnar <mingo@kernel.org>
Sat, 29 Apr 2023 07:09:16 +0000 (09:09 +0200)
Implement target specific support for local_try_cmpxchg()
and local_cmpxchg() using typed C wrappers that call their
_local counterpart and provide additional checking of
their input arguments.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230405141710.3551-4-ubizjak@gmail.com
Cc: Linus Torvalds <torvalds@linux-foundation.org>
arch/alpha/include/asm/local.h
arch/loongarch/include/asm/local.h
arch/mips/include/asm/local.h
arch/powerpc/include/asm/local.h
arch/x86/include/asm/local.h

index fab26a1c93d5af7412e69271f4467b56bb64576c..0fcaad642cc3ea7c943a5b72732bd0874fc51c0b 100644 (file)
@@ -52,8 +52,16 @@ static __inline__ long local_sub_return(long i, local_t * l)
        return result;
 }
 
-#define local_cmpxchg(l, o, n) \
-       (cmpxchg_local(&((l)->a.counter), (o), (n)))
+static __inline__ long local_cmpxchg(local_t *l, long old, long new)
+{
+       return cmpxchg_local(&l->a.counter, old, new);
+}
+
+static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
+{
+       return try_cmpxchg_local(&l->a.counter, (s64 *)old, new);
+}
+
 #define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
 
 /**
index 65fbbae9fc4da7b82f02d97499b40285491a2f44..83e995b30e472b69b6e47ef0ab9441c27a49ef31 100644 (file)
@@ -56,8 +56,17 @@ static inline long local_sub_return(long i, local_t *l)
        return result;
 }
 
-#define local_cmpxchg(l, o, n) \
-       ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+static inline long local_cmpxchg(local_t *l, long old, long new)
+{
+       return cmpxchg_local(&l->a.counter, old, new);
+}
+
+static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
+{
+       typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+       return try_cmpxchg_local(&l->a.counter, __old, new);
+}
+
 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
index 08366b1fd273d77a26acb3adcf7afa72e7f9222d..5daf6fe8e3e9afbcbf3b6301c909cb50d55e71aa 100644 (file)
@@ -94,8 +94,17 @@ static __inline__ long local_sub_return(long i, local_t * l)
        return result;
 }
 
-#define local_cmpxchg(l, o, n) \
-       ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+static __inline__ long local_cmpxchg(local_t *l, long old, long new)
+{
+       return cmpxchg_local(&l->a.counter, old, new);
+}
+
+static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
+{
+       typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+       return try_cmpxchg_local(&l->a.counter, __old, new);
+}
+
 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
index bc4bd19b7fc235b80ec1132f44409b6fe1057975..45492fb5bf223cbd1870b202bd21dc5cdc98a708 100644 (file)
@@ -90,6 +90,17 @@ static __inline__ long local_cmpxchg(local_t *l, long o, long n)
        return t;
 }
 
+static __inline__ bool local_try_cmpxchg(local_t *l, long *po, long n)
+{
+       long o = *po, r;
+
+       r = local_cmpxchg(l, o, n);
+       if (unlikely(r != o))
+               *po = r;
+
+       return likely(r == o);
+}
+
 static __inline__ long local_xchg(local_t *l, long n)
 {
        long t;
index 349a47acaa4a3524e25f056152cd701bd2c26224..56d4ef604b919a477657e8ab0a9bd5c43d9ce4a0 100644 (file)
@@ -120,8 +120,17 @@ static inline long local_sub_return(long i, local_t *l)
 #define local_inc_return(l)  (local_add_return(1, l))
 #define local_dec_return(l)  (local_sub_return(1, l))
 
-#define local_cmpxchg(l, o, n) \
-       (cmpxchg_local(&((l)->a.counter), (o), (n)))
+static inline long local_cmpxchg(local_t *l, long old, long new)
+{
+       return cmpxchg_local(&l->a.counter, old, new);
+}
+
+static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
+{
+       typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+       return try_cmpxchg_local(&l->a.counter, __old, new);
+}
+
 /* Always has a lock prefix */
 #define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))