forked from Minki/linux
locking/atomic: arc: move to ARCH_ATOMIC
We'd like all architectures to convert to ARCH_ATOMIC, as once all architectures are converted it will be possible to make significant cleanups to the atomics headers, and this will make it much easier to generically enable atomic functionality (e.g. debug logic in the instrumented wrappers). As a step towards that, this patch migrates alpha to ARCH_ATOMIC. The arch code provides arch_{atomic,atomic64,xchg,cmpxchg}*(), and common code wraps these with optional instrumentation to provide the regular functions. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Vineet Gupta <vgupta@synopsys.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20210525140232.53872-15-mark.rutland@arm.com
This commit is contained in:
parent
96d330aff7
commit
6db5d99304
@ -6,6 +6,7 @@
|
||||
config ARC
|
||||
def_bool y
|
||||
select ARC_TIMERS
|
||||
select ARCH_ATOMIC
|
||||
select ARCH_HAS_CACHE_LINE_SIZE
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DMA_PREP_COHERENT
|
||||
|
@ -14,14 +14,14 @@
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define atomic_read(v) READ_ONCE((v)->counter)
|
||||
#define arch_atomic_read(v) READ_ONCE((v)->counter)
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_LLSC
|
||||
|
||||
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
#define arch_atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
|
||||
#define ATOMIC_OP(op, c_op, asm_op) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
static inline void arch_atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned int val; \
|
||||
\
|
||||
@ -37,7 +37,7 @@ static inline void atomic_##op(int i, atomic_t *v) \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
static inline int arch_atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned int val; \
|
||||
\
|
||||
@ -63,7 +63,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
static inline int arch_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned int val, orig; \
|
||||
\
|
||||
@ -94,11 +94,11 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
/* violating atomic_xxx API locking protocol in UP for optimization sake */
|
||||
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
#define arch_atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
|
||||
#else
|
||||
|
||||
static inline void atomic_set(atomic_t *v, int i)
|
||||
static inline void arch_atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
/*
|
||||
* Independent of hardware support, all of the atomic_xxx() APIs need
|
||||
@ -116,7 +116,7 @@ static inline void atomic_set(atomic_t *v, int i)
|
||||
atomic_ops_unlock(flags);
|
||||
}
|
||||
|
||||
#define atomic_set_release(v, i) atomic_set((v), (i))
|
||||
#define arch_atomic_set_release(v, i) arch_atomic_set((v), (i))
|
||||
|
||||
#endif
|
||||
|
||||
@ -126,7 +126,7 @@ static inline void atomic_set(atomic_t *v, int i)
|
||||
*/
|
||||
|
||||
#define ATOMIC_OP(op, c_op, asm_op) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
static inline void arch_atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -136,7 +136,7 @@ static inline void atomic_##op(int i, atomic_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
static inline int arch_atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
unsigned long temp; \
|
||||
@ -154,7 +154,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
static inline int arch_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
unsigned long orig; \
|
||||
@ -180,9 +180,6 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
ATOMIC_OPS(add, +=, add)
|
||||
ATOMIC_OPS(sub, -=, sub)
|
||||
|
||||
#define atomic_andnot atomic_andnot
|
||||
#define atomic_fetch_andnot atomic_fetch_andnot
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#define ATOMIC_OPS(op, c_op, asm_op) \
|
||||
ATOMIC_OP(op, c_op, asm_op) \
|
||||
@ -193,6 +190,9 @@ ATOMIC_OPS(andnot, &= ~, bic)
|
||||
ATOMIC_OPS(or, |=, or)
|
||||
ATOMIC_OPS(xor, ^=, xor)
|
||||
|
||||
#define arch_atomic_andnot arch_atomic_andnot
|
||||
#define arch_atomic_fetch_andnot arch_atomic_fetch_andnot
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_FETCH_OP
|
||||
#undef ATOMIC_OP_RETURN
|
||||
@ -220,7 +220,7 @@ typedef struct {
|
||||
|
||||
#define ATOMIC64_INIT(a) { (a) }
|
||||
|
||||
static inline s64 atomic64_read(const atomic64_t *v)
|
||||
static inline s64 arch_atomic64_read(const atomic64_t *v)
|
||||
{
|
||||
s64 val;
|
||||
|
||||
@ -232,7 +232,7 @@ static inline s64 atomic64_read(const atomic64_t *v)
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void atomic64_set(atomic64_t *v, s64 a)
|
||||
static inline void arch_atomic64_set(atomic64_t *v, s64 a)
|
||||
{
|
||||
/*
|
||||
* This could have been a simple assignment in "C" but would need
|
||||
@ -253,7 +253,7 @@ static inline void atomic64_set(atomic64_t *v, s64 a)
|
||||
}
|
||||
|
||||
#define ATOMIC64_OP(op, op1, op2) \
|
||||
static inline void atomic64_##op(s64 a, atomic64_t *v) \
|
||||
static inline void arch_atomic64_##op(s64 a, atomic64_t *v) \
|
||||
{ \
|
||||
s64 val; \
|
||||
\
|
||||
@ -270,7 +270,7 @@ static inline void atomic64_##op(s64 a, atomic64_t *v) \
|
||||
} \
|
||||
|
||||
#define ATOMIC64_OP_RETURN(op, op1, op2) \
|
||||
static inline s64 atomic64_##op##_return(s64 a, atomic64_t *v) \
|
||||
static inline s64 arch_atomic64_##op##_return(s64 a, atomic64_t *v) \
|
||||
{ \
|
||||
s64 val; \
|
||||
\
|
||||
@ -293,7 +293,7 @@ static inline s64 atomic64_##op##_return(s64 a, atomic64_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC64_FETCH_OP(op, op1, op2) \
|
||||
static inline s64 atomic64_fetch_##op(s64 a, atomic64_t *v) \
|
||||
static inline s64 arch_atomic64_fetch_##op(s64 a, atomic64_t *v) \
|
||||
{ \
|
||||
s64 val, orig; \
|
||||
\
|
||||
@ -320,9 +320,6 @@ static inline s64 atomic64_fetch_##op(s64 a, atomic64_t *v) \
|
||||
ATOMIC64_OP_RETURN(op, op1, op2) \
|
||||
ATOMIC64_FETCH_OP(op, op1, op2)
|
||||
|
||||
#define atomic64_andnot atomic64_andnot
|
||||
#define atomic64_fetch_andnot atomic64_fetch_andnot
|
||||
|
||||
ATOMIC64_OPS(add, add.f, adc)
|
||||
ATOMIC64_OPS(sub, sub.f, sbc)
|
||||
ATOMIC64_OPS(and, and, and)
|
||||
@ -330,13 +327,16 @@ ATOMIC64_OPS(andnot, bic, bic)
|
||||
ATOMIC64_OPS(or, or, or)
|
||||
ATOMIC64_OPS(xor, xor, xor)
|
||||
|
||||
#define arch_atomic64_andnot arch_atomic64_andnot
|
||||
#define arch_atomic64_fetch_andnot arch_atomic64_fetch_andnot
|
||||
|
||||
#undef ATOMIC64_OPS
|
||||
#undef ATOMIC64_FETCH_OP
|
||||
#undef ATOMIC64_OP_RETURN
|
||||
#undef ATOMIC64_OP
|
||||
|
||||
static inline s64
|
||||
atomic64_cmpxchg(atomic64_t *ptr, s64 expected, s64 new)
|
||||
arch_atomic64_cmpxchg(atomic64_t *ptr, s64 expected, s64 new)
|
||||
{
|
||||
s64 prev;
|
||||
|
||||
@ -358,7 +358,7 @@ atomic64_cmpxchg(atomic64_t *ptr, s64 expected, s64 new)
|
||||
return prev;
|
||||
}
|
||||
|
||||
static inline s64 atomic64_xchg(atomic64_t *ptr, s64 new)
|
||||
static inline s64 arch_atomic64_xchg(atomic64_t *ptr, s64 new)
|
||||
{
|
||||
s64 prev;
|
||||
|
||||
@ -379,14 +379,14 @@ static inline s64 atomic64_xchg(atomic64_t *ptr, s64 new)
|
||||
}
|
||||
|
||||
/**
|
||||
* atomic64_dec_if_positive - decrement by 1 if old value positive
|
||||
* arch_atomic64_dec_if_positive - decrement by 1 if old value positive
|
||||
* @v: pointer of type atomic64_t
|
||||
*
|
||||
* The function returns the old value of *v minus 1, even if
|
||||
* the atomic variable, v, was not decremented.
|
||||
*/
|
||||
|
||||
static inline s64 atomic64_dec_if_positive(atomic64_t *v)
|
||||
static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
|
||||
{
|
||||
s64 val;
|
||||
|
||||
@ -408,10 +408,10 @@ static inline s64 atomic64_dec_if_positive(atomic64_t *v)
|
||||
|
||||
return val;
|
||||
}
|
||||
#define atomic64_dec_if_positive atomic64_dec_if_positive
|
||||
#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
|
||||
|
||||
/**
|
||||
* atomic64_fetch_add_unless - add unless the number is a given value
|
||||
* arch_atomic64_fetch_add_unless - add unless the number is a given value
|
||||
* @v: pointer of type atomic64_t
|
||||
* @a: the amount to add to v...
|
||||
* @u: ...unless v is equal to u.
|
||||
@ -419,7 +419,7 @@ static inline s64 atomic64_dec_if_positive(atomic64_t *v)
|
||||
* Atomically adds @a to @v, if it was not @u.
|
||||
* Returns the old value of @v
|
||||
*/
|
||||
static inline s64 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
static inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
{
|
||||
s64 old, temp;
|
||||
|
||||
@ -443,7 +443,7 @@ static inline s64 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
|
||||
return old;
|
||||
}
|
||||
#define atomic64_fetch_add_unless atomic64_fetch_add_unless
|
||||
#define arch_atomic64_fetch_add_unless arch_atomic64_fetch_add_unless
|
||||
|
||||
#endif /* !CONFIG_GENERIC_ATOMIC64 */
|
||||
|
||||
|
@ -63,7 +63,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
|
||||
|
||||
#endif
|
||||
|
||||
#define cmpxchg(ptr, o, n) ({ \
|
||||
#define arch_cmpxchg(ptr, o, n) ({ \
|
||||
(typeof(*(ptr)))__cmpxchg((ptr), \
|
||||
(unsigned long)(o), \
|
||||
(unsigned long)(n)); \
|
||||
@ -75,7 +75,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
|
||||
* !LLSC: cmpxchg() has to use an external lock atomic_ops_lock to guarantee
|
||||
* semantics, and this lock also happens to be used by atomic_*()
|
||||
*/
|
||||
#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define arch_atomic_cmpxchg(v, o, n) ((int)arch_cmpxchg(&((v)->counter), (o), (n)))
|
||||
|
||||
|
||||
/*
|
||||
@ -123,7 +123,7 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
|
||||
|
||||
#if !defined(CONFIG_ARC_HAS_LLSC) && defined(CONFIG_SMP)
|
||||
|
||||
#define xchg(ptr, with) \
|
||||
#define arch_xchg(ptr, with) \
|
||||
({ \
|
||||
unsigned long flags; \
|
||||
typeof(*(ptr)) old_val; \
|
||||
@ -136,7 +136,7 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
|
||||
|
||||
#else
|
||||
|
||||
#define xchg(ptr, with) _xchg(ptr, with)
|
||||
#define arch_xchg(ptr, with) _xchg(ptr, with)
|
||||
|
||||
#endif
|
||||
|
||||
@ -153,6 +153,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
|
||||
* can't be clobbered by others. Thus no serialization required when
|
||||
* atomic_xchg is involved.
|
||||
*/
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
#define arch_atomic_xchg(v, new) (arch_xchg(&((v)->counter), new))
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user