From: Simon Glass <simon.glass@canonical.com> Move xchg and try_cmpxchg macros to asm-generic/atomic.h alongside cmpxchg, as they are all atomic exchange operations. Add: - try_cmpxchg() - compare and exchange with boolean return and old value update on failure - xchg() - atomic exchange, stores new value and returns old These are single-threaded implementations for U-Boot. Add #ifndef guards to all three macros (cmpxchg, try_cmpxchg, xchg) to avoid redefinition warnings on architectures like MIPS that provide their own implementations. Signed-off-by: Simon Glass <simon.glass@canonical.com> Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> --- fs/ext4l/ext4_uboot.h | 12 ++---------- include/asm-generic/atomic.h | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index a4d863b86e1..a4baac6fc86 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -949,14 +949,7 @@ typedef unsigned int projid_t; * Additional stubs for inode.c */ -/* try_cmpxchg - compare and exchange with return value */ -#define try_cmpxchg(ptr, old, new) ({ \ - typeof(*(old)) __old = *(old); \ - typeof(*(ptr)) __ret = cmpxchg(ptr, __old, (new)); \ - if (__ret != __old) \ - *(old) = __ret; \ - __ret == __old; \ -}) +/* try_cmpxchg is now in asm-generic/atomic.h */ /* hash_64 - simple 64-bit hash */ #define hash_64(val, bits) ((unsigned long)((val) >> (64 - (bits)))) @@ -1743,8 +1736,7 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, /* refcount operations are now in linux/refcount.h */ -/* xchg - exchange value atomically */ -#define xchg(ptr, new) ({ typeof(*(ptr)) __old = *(ptr); *(ptr) = (new); __old; }) +/* xchg is now in asm-generic/atomic.h */ /* printk_ratelimited is in linux/printk.h */ diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 3fa749bf012..3f72ae39ee1 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -209,6 +209,7 @@ static inline void atomic64_dec(volatile atomic64_t *v) * Single-threaded version for U-Boot. Atomically compares *ptr with old * and if equal, stores new. Returns the original value of *ptr. */ +#ifndef cmpxchg #define cmpxchg(ptr, old, new) ({ \ typeof(*(ptr)) __cmpxchg_old = (old); \ typeof(*(ptr)) __cmpxchg_new = (new); \ @@ -217,5 +218,41 @@ static inline void atomic64_dec(volatile atomic64_t *v) *(ptr) = __cmpxchg_new; \ __cmpxchg_ret; \ }) +#endif + +/** + * try_cmpxchg - compare and exchange with boolean return + * @ptr: pointer to the value + * @oldp: pointer to expected old value (updated on failure) + * @new: new value to store if current equals old + * + * Returns true if exchange succeeded, false otherwise. + * On failure, *oldp is updated with the current value. + */ +#ifndef try_cmpxchg +#define try_cmpxchg(ptr, oldp, new) ({ \ + typeof(*(oldp)) __old = *(oldp); \ + typeof(*(ptr)) __ret = cmpxchg(ptr, __old, (new)); \ + if (__ret != __old) \ + *(oldp) = __ret; \ + __ret == __old; \ +}) +#endif + +/** + * xchg - exchange value atomically + * @ptr: pointer to the value + * @new: new value to store + * + * Atomically stores new value and returns the old value. + * Single-threaded version for U-Boot. + */ +#ifndef xchg +#define xchg(ptr, new) ({ \ + typeof(*(ptr)) __xchg_old = *(ptr); \ + *(ptr) = (new); \ + __xchg_old; \ +}) +#endif #endif -- 2.43.0