1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2acac43e2SArun Sharma /* Atomic operations usable in machine independent code */ 33f9d35b9SEric Dumazet #ifndef _LINUX_ATOMIC_H 43f9d35b9SEric Dumazet #define _LINUX_ATOMIC_H 5ade5ef92SMark Rutland #include <linux/types.h> 6ade5ef92SMark Rutland 73f9d35b9SEric Dumazet #include <asm/atomic.h> 8654672d4SWill Deacon #include <asm/barrier.h> 9654672d4SWill Deacon 10654672d4SWill Deacon /* 11654672d4SWill Deacon * Relaxed variants of xchg, cmpxchg and some atomic operations. 12654672d4SWill Deacon * 13654672d4SWill Deacon * We support four variants: 14654672d4SWill Deacon * 15654672d4SWill Deacon * - Fully ordered: The default implementation, no suffix required. 16654672d4SWill Deacon * - Acquire: Provides ACQUIRE semantics, _acquire suffix. 17654672d4SWill Deacon * - Release: Provides RELEASE semantics, _release suffix. 18654672d4SWill Deacon * - Relaxed: No ordering guarantees, _relaxed suffix. 19654672d4SWill Deacon * 20654672d4SWill Deacon * For compound atomics performing both a load and a store, ACQUIRE 21654672d4SWill Deacon * semantics apply only to the load and RELEASE semantics only to the 22654672d4SWill Deacon * store portion of the operation. Note that a failed cmpxchg_acquire 23654672d4SWill Deacon * does -not- imply any memory ordering constraints. 24654672d4SWill Deacon * 25654672d4SWill Deacon * See Documentation/memory-barriers.txt for ACQUIRE/RELEASE definitions. 26654672d4SWill Deacon */ 27654672d4SWill Deacon 2837f8173dSPeter Zijlstra #define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) 2937f8173dSPeter Zijlstra #define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) 3037f8173dSPeter Zijlstra 3137f8173dSPeter Zijlstra #define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) 3237f8173dSPeter Zijlstra #define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) 3337f8173dSPeter Zijlstra 34654672d4SWill Deacon /* 35654672d4SWill Deacon * The idea here is to build acquire/release variants by adding explicit 36654672d4SWill Deacon * barriers on top of the relaxed variant. In the case where the relaxed 37654672d4SWill Deacon * variant is already fully ordered, no additional barriers are needed. 38e1ab7f39SBoqun Feng * 39fd2efaa4SMark Rutland * If an architecture overrides __atomic_acquire_fence() it will probably 40fd2efaa4SMark Rutland * want to define smp_mb__after_spinlock(). 41654672d4SWill Deacon */ 42fd2efaa4SMark Rutland #ifndef __atomic_acquire_fence 43fd2efaa4SMark Rutland #define __atomic_acquire_fence smp_mb__after_atomic 44fd2efaa4SMark Rutland #endif 45fd2efaa4SMark Rutland 46fd2efaa4SMark Rutland #ifndef __atomic_release_fence 47fd2efaa4SMark Rutland #define __atomic_release_fence smp_mb__before_atomic 48fd2efaa4SMark Rutland #endif 49fd2efaa4SMark Rutland 50fd2efaa4SMark Rutland #ifndef __atomic_pre_full_fence 51fd2efaa4SMark Rutland #define __atomic_pre_full_fence smp_mb__before_atomic 52fd2efaa4SMark Rutland #endif 53fd2efaa4SMark Rutland 54fd2efaa4SMark Rutland #ifndef __atomic_post_full_fence 55fd2efaa4SMark Rutland #define __atomic_post_full_fence smp_mb__after_atomic 56fd2efaa4SMark Rutland #endif 57fd2efaa4SMark Rutland 58654672d4SWill Deacon #define __atomic_op_acquire(op, args...) \ 59654672d4SWill Deacon ({ \ 60654672d4SWill Deacon typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ 61fd2efaa4SMark Rutland __atomic_acquire_fence(); \ 62654672d4SWill Deacon __ret; \ 63654672d4SWill Deacon }) 64654672d4SWill Deacon 65654672d4SWill Deacon #define __atomic_op_release(op, args...) \ 66654672d4SWill Deacon ({ \ 67fd2efaa4SMark Rutland __atomic_release_fence(); \ 68654672d4SWill Deacon op##_relaxed(args); \ 69654672d4SWill Deacon }) 70654672d4SWill Deacon 71654672d4SWill Deacon #define __atomic_op_fence(op, args...) \ 72654672d4SWill Deacon ({ \ 73654672d4SWill Deacon typeof(op##_relaxed(args)) __ret; \ 74fd2efaa4SMark Rutland __atomic_pre_full_fence(); \ 75654672d4SWill Deacon __ret = op##_relaxed(args); \ 76fd2efaa4SMark Rutland __atomic_post_full_fence(); \ 77654672d4SWill Deacon __ret; \ 78654672d4SWill Deacon }) 79654672d4SWill Deacon 80e3d18ceeSMark Rutland #include <linux/atomic/atomic-arch-fallback.h> 81*1815da17SMark Rutland #include <linux/atomic/atomic-long.h> 8267d1b0deSMark Rutland #include <linux/atomic/atomic-instrumented.h> 8390fe6514SPeter Zijlstra 843f9d35b9SEric Dumazet #endif /* _LINUX_ATOMIC_H */ 85