Commit 62e8a325 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

atomic, arch: Audit atomic_{read,set}()



This patch makes sure that atomic_{read,set}() are at least
{READ,WRITE}_ONCE().

We already had the 'requirement' that atomic_read() should use
ACCESS_ONCE(), and most archs had this, but a few were lacking.
All are now converted to use READ_ONCE().

And, by a symmetry and general paranoia argument, upgrade atomic_set()
to use WRITE_ONCE().

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: james.hogan@imgtec.com
Cc: linux-kernel@vger.kernel.org
Cc: oleg@redhat.com
Cc: will.deacon@arm.com
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 90fe6514
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -17,11 +17,11 @@
#define ATOMIC_INIT(i)		{ (i) }
#define ATOMIC64_INIT(i)	{ (i) }

#define atomic_read(v)		ACCESS_ONCE((v)->counter)
#define atomic64_read(v)	ACCESS_ONCE((v)->counter)
#define atomic_read(v)		READ_ONCE((v)->counter)
#define atomic64_read(v)	READ_ONCE((v)->counter)

#define atomic_set(v,i)		((v)->counter = (i))
#define atomic64_set(v,i)	((v)->counter = (i))
#define atomic_set(v,i)		WRITE_ONCE((v)->counter, (i))
#define atomic64_set(v,i)	WRITE_ONCE((v)->counter, (i))

/*
 * To get proper branch prediction for the main line, we must branch
+4 −4
Original line number Diff line number Diff line
@@ -17,11 +17,11 @@
#include <asm/barrier.h>
#include <asm/smp.h>

#define atomic_read(v)  ((v)->counter)
#define atomic_read(v)  READ_ONCE((v)->counter)

#ifdef CONFIG_ARC_HAS_LLSC

#define atomic_set(v, i) (((v)->counter) = (i))
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))

#ifdef CONFIG_ARC_STAR_9000923308

@@ -107,7 +107,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
#ifndef CONFIG_SMP

 /* violating atomic_xxx API locking protocol in UP for optimization sake */
#define atomic_set(v, i) (((v)->counter) = (i))
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))

#else

@@ -125,7 +125,7 @@ static inline void atomic_set(atomic_t *v, int i)
	unsigned long flags;

	atomic_ops_lock(flags);
	v->counter = i;
	WRITE_ONCE(v->counter, i);
	atomic_ops_unlock(flags);
}

+2 −2
Original line number Diff line number Diff line
@@ -27,8 +27,8 @@
 * strex/ldrex monitor on some implementations. The reason we can use it for
 * atomic_set() is the clrex or dummy strex done on every exception return.
 */
#define atomic_read(v)	ACCESS_ONCE((v)->counter)
#define atomic_set(v,i)	(((v)->counter) = (i))
#define atomic_read(v)	READ_ONCE((v)->counter)
#define atomic_set(v,i)	WRITE_ONCE(((v)->counter), (i))

#if __LINUX_ARM_ARCH__ >= 6

+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@
#define ATOMIC_INIT(i)	{ (i) }

#define atomic_read(v)			READ_ONCE((v)->counter)
#define atomic_set(v, i)		(((v)->counter) = (i))
#define atomic_set(v, i)		WRITE_ONCE(((v)->counter), (i))
#define atomic_xchg(v, new)		xchg(&((v)->counter), (new))
#define atomic_cmpxchg(v, old, new)	cmpxchg(&((v)->counter), (old), (new))

+2 −2
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@

#define ATOMIC_INIT(i)  { (i) }

#define atomic_read(v)		ACCESS_ONCE((v)->counter)
#define atomic_set(v, i)	(((v)->counter) = i)
#define atomic_read(v)		READ_ONCE((v)->counter)
#define atomic_set(v, i)	WRITE_ONCE(((v)->counter), (i))

#define ATOMIC_OP_RETURN(op, asm_op, asm_con)				\
static inline int __atomic_##op##_return(int i, atomic_t *v)		\
Loading