mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Currently a number of arch_atomic*_<op>() functions are optional, and where an arch does not provide a given arch_atomic*_<op>() we will define an implementation of arch_atomic*_<op>() in atomic-arch-fallback.h. Filling in the missing ops requires special care as we want to select the optimal definition of each op (e.g. preferentially defining ops in terms of their relaxed form rather than their fully-ordered form). The ifdeffery necessary for this requires us to group ordering variants together, which can be a bit painful to read, and is painful for kerneldoc generation. It would be easier to handle this if we generated ops into a separate namespace, as this would remove the need to take special care with the ifdeffery, and allow each ordering variant to be generated separately. This patch adds a new set of raw_atomic_<op>() definitions, which are currently trivial wrappers of their arch_atomic_<op>() equivalent. This will allow us to move treewide users of arch_atomic_<op>() over to raw atomic op before we rework the fallback generation to generate raw_atomic_<op> directly. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20230605070124.3741859-18-mark.rutland@arm.com
86 lines
2.6 KiB
C
86 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Atomic operations usable in machine independent code */
|
|
#ifndef _LINUX_ATOMIC_H
|
|
#define _LINUX_ATOMIC_H
|
|
#include <linux/types.h>
|
|
|
|
#include <asm/atomic.h>
|
|
#include <asm/barrier.h>
|
|
|
|
/*
|
|
* Relaxed variants of xchg, cmpxchg and some atomic operations.
|
|
*
|
|
* We support four variants:
|
|
*
|
|
* - Fully ordered: The default implementation, no suffix required.
|
|
* - Acquire: Provides ACQUIRE semantics, _acquire suffix.
|
|
* - Release: Provides RELEASE semantics, _release suffix.
|
|
* - Relaxed: No ordering guarantees, _relaxed suffix.
|
|
*
|
|
* For compound atomics performing both a load and a store, ACQUIRE
|
|
* semantics apply only to the load and RELEASE semantics only to the
|
|
* store portion of the operation. Note that a failed cmpxchg_acquire
|
|
* does -not- imply any memory ordering constraints.
|
|
*
|
|
* See Documentation/memory-barriers.txt for ACQUIRE/RELEASE definitions.
|
|
*/
|
|
|
|
#define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
|
|
#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
|
|
|
|
#define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
|
|
#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
|
|
|
|
/*
|
|
* The idea here is to build acquire/release variants by adding explicit
|
|
* barriers on top of the relaxed variant. In the case where the relaxed
|
|
* variant is already fully ordered, no additional barriers are needed.
|
|
*
|
|
* If an architecture overrides __atomic_acquire_fence() it will probably
|
|
* want to define smp_mb__after_spinlock().
|
|
*/
|
|
#ifndef __atomic_acquire_fence
|
|
#define __atomic_acquire_fence smp_mb__after_atomic
|
|
#endif
|
|
|
|
#ifndef __atomic_release_fence
|
|
#define __atomic_release_fence smp_mb__before_atomic
|
|
#endif
|
|
|
|
#ifndef __atomic_pre_full_fence
|
|
#define __atomic_pre_full_fence smp_mb__before_atomic
|
|
#endif
|
|
|
|
#ifndef __atomic_post_full_fence
|
|
#define __atomic_post_full_fence smp_mb__after_atomic
|
|
#endif
|
|
|
|
#define __atomic_op_acquire(op, args...) \
|
|
({ \
|
|
typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
|
|
__atomic_acquire_fence(); \
|
|
__ret; \
|
|
})
|
|
|
|
#define __atomic_op_release(op, args...) \
|
|
({ \
|
|
__atomic_release_fence(); \
|
|
op##_relaxed(args); \
|
|
})
|
|
|
|
#define __atomic_op_fence(op, args...) \
|
|
({ \
|
|
typeof(op##_relaxed(args)) __ret; \
|
|
__atomic_pre_full_fence(); \
|
|
__ret = op##_relaxed(args); \
|
|
__atomic_post_full_fence(); \
|
|
__ret; \
|
|
})
|
|
|
|
#include <linux/atomic/atomic-arch-fallback.h>
|
|
#include <linux/atomic/atomic-long.h>
|
|
#include <linux/atomic/atomic-raw.h>
|
|
#include <linux/atomic/atomic-instrumented.h>
|
|
|
|
#endif /* _LINUX_ATOMIC_H */
|