mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mark Rutland <mark.rutland@arm.com>
To: linux-kernel@vger.kernel.org, will.deacon@arm.com,
	peterz@infradead.org, boqun.feng@gmail.com
Cc: Mark Rutland <mark.rutland@arm.com>,
	Andrea Parri <parri.andrea@gmail.com>
Subject: [PATCHv2 06/11] atomics/treewide: rework ordering barriers
Date: Mon, 25 Jun 2018 11:59:47 +0100	[thread overview]
Message-ID: <20180625105952.3756-7-mark.rutland@arm.com> (raw)
In-Reply-To: <20180625105952.3756-1-mark.rutland@arm.com>

Currently architectures can override __atomic_op_*() to define the barriers
used before/after a relaxed atomic when used to build acquire/release/fence
variants.

This has the unfortunate property of requiring the architecture to define the
full wrapper for the atomics, rather than just the barriers they care about,
and gets in the way of generating atomics which can be easily read.

Instead, this patch has architectures define an optional set of barriers,
__atomic_mb_{before,after}_{acquire,release,fence}(), which <linux/atomic.h>
uses to build the wrappers.

At the same time, let's avoid any potential reliance on these elsewhere
by ensuring each is undef'd at the end of <linux/atomic.h>.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Andrea Parri <parri.andrea@gmail.com>
---
 arch/alpha/include/asm/atomic.h   |  8 +++----
 arch/powerpc/include/asm/atomic.h | 17 +++++---------
 arch/riscv/include/asm/atomic.h   | 17 +++++---------
 include/linux/atomic.h            | 47 ++++++++++++++++++++++++++-------------
 4 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
index 4a6a8f58c9c9..df8d9aa2a47e 100644
--- a/arch/alpha/include/asm/atomic.h
+++ b/arch/alpha/include/asm/atomic.h
@@ -18,11 +18,11 @@
  * To ensure dependency ordering is preserved for the _relaxed and
  * _release atomics, an smp_read_barrier_depends() is unconditionally
  * inserted into the _relaxed variants, which are used to build the
- * barriered versions. To avoid redundant back-to-back fences, we can
- * define the _acquire and _fence versions explicitly.
+ * barriered versions. Avoid redundant back-to-back fences in the
+ * _acquire and _fence versions.
  */
-#define __atomic_op_acquire(op, args...)	op##_relaxed(args)
-#define __atomic_op_fence			__atomic_op_release
+#define __atomic_acquire_fence()
+#define __atomic_post_fence()
 
 #define ATOMIC_INIT(i)		{ (i) }
 #define ATOMIC64_INIT(i)	{ (i) }
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index a0156cb43d1f..963abf8bf1c0 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -18,18 +18,11 @@
  * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
  * on the platform without lwsync.
  */
-#define __atomic_op_acquire(op, args...)				\
-({									\
-	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
-	__asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory");	\
-	__ret;								\
-})
-
-#define __atomic_op_release(op, args...)				\
-({									\
-	__asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory");	\
-	op##_relaxed(args);						\
-})
+#define __atomic_acquire_fence()					\
+	__asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory")
+
+#define __atomic_release_fence()					\
+	__asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory")
 
 static __inline__ int atomic_read(const atomic_t *v)
 {
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 512b89485790..c452359c9cb8 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -25,18 +25,11 @@
 
 #define ATOMIC_INIT(i)	{ (i) }
 
-#define __atomic_op_acquire(op, args...)				\
-({									\
-	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
-	__asm__ __volatile__(RISCV_ACQUIRE_BARRIER "" ::: "memory");	\
-	__ret;								\
-})
-
-#define __atomic_op_release(op, args...)				\
-({									\
-	__asm__ __volatile__(RISCV_RELEASE_BARRIER "" ::: "memory");	\
-	op##_relaxed(args);						\
-})
+#define __atomic_acquire_fence()					\
+	__asm__ __volatile__(RISCV_ACQUIRE_BARRIER "" ::: "memory")
+
+#define __atomic_release_fence()					\
+	__asm__ __volatile__(RISCV_RELEASE_BARRIER "" ::: "memory");
 
 static __always_inline int atomic_read(const atomic_t *v)
 {
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 8e04f1f69bd9..fc39e4bead30 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -38,40 +38,46 @@
  * barriers on top of the relaxed variant. In the case where the relaxed
  * variant is already fully ordered, no additional barriers are needed.
  *
- * Besides, if an arch has a special barrier for acquire/release, it could
- * implement its own __atomic_op_* and use the same framework for building
- * variants
- *
- * If an architecture overrides __atomic_op_acquire() it will probably want
- * to define smp_mb__after_spinlock().
+ * If an architecture overrides __atomic_acquire_fence() it will probably
+ * want to define smp_mb__after_spinlock().
  */
-#ifndef __atomic_op_acquire
+#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_fence
+#define __atomic_pre_fence		smp_mb__before_atomic
+#endif
+
+#ifndef __atomic_post_fence
+#define __atomic_post_fence		smp_mb__after_atomic
+#endif
+
 #define __atomic_op_acquire(op, args...)				\
 ({									\
 	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
-	smp_mb__after_atomic();						\
+	__atomic_acquire_fence();					\
 	__ret;								\
 })
-#endif
 
-#ifndef __atomic_op_release
 #define __atomic_op_release(op, args...)				\
 ({									\
-	smp_mb__before_atomic();					\
+	__atomic_release_fence();					\
 	op##_relaxed(args);						\
 })
-#endif
 
-#ifndef __atomic_op_fence
 #define __atomic_op_fence(op, args...)					\
 ({									\
 	typeof(op##_relaxed(args)) __ret;				\
-	smp_mb__before_atomic();					\
+	__atomic_pre_fence();						\
 	__ret = op##_relaxed(args);					\
-	smp_mb__after_atomic();						\
+	__atomic_post_fence();						\
 	__ret;								\
 })
-#endif
 
 /* atomic_add_return_relaxed */
 #ifndef atomic_add_return_relaxed
@@ -1308,4 +1314,13 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
 
 #include <asm-generic/atomic-long.h>
 
+#undef __atomic_op_acquire
+#undef __atomic_op_release
+#undef __atomic_op_fence
+
+#undef __atomic_acquire_fence
+#undef __atomic_release_fence
+#undef __atomic_pre_fence
+#undef __atomic_post_fence
+
 #endif /* _LINUX_ATOMIC_H */
-- 
2.11.0


  parent reply	other threads:[~2018-06-25 11:01 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-25 10:59 [PATCHv2 00/11] atomics: generate atomic headers / instrument arm64 Mark Rutland
2018-06-25 10:59 ` [PATCHv2 01/11] atomic/tty: Fix up atomic abuse in ldsem Mark Rutland
2018-06-26 18:53   ` Andy Shevchenko
2018-06-26 19:30     ` Peter Zijlstra
2018-06-27 17:33       ` Andy Shevchenko
2018-06-25 10:59 ` [PATCHv2 02/11] atomics/x86: reduce arch_cmpxchg64*() instrumentation Mark Rutland
2018-06-25 10:59 ` [PATCHv2 03/11] atomics: simplify cmpxchg() instrumentation Mark Rutland
2018-06-25 11:38   ` Andrea Parri
2018-06-25 11:47     ` Dmitry Vyukov
2018-06-25 11:48     ` Mark Rutland
2018-06-25 10:59 ` [PATCHv2 04/11] atomics/treewide: instrument xchg() Mark Rutland
2018-06-25 10:59 ` [PATCHv2 05/11] atomics: instrument cmpxchg_double*() Mark Rutland
2018-06-25 10:59 ` Mark Rutland [this message]
2018-06-25 15:44   ` [PATCHv2 06/11] atomics/treewide: rework ordering barriers Mark Rutland
2018-07-04 15:06   ` Will Deacon
2018-07-04 15:56     ` Mark Rutland
2018-07-04 17:50       ` Will Deacon
2018-07-05 10:12         ` Mark Rutland
2018-07-05 16:25           ` Will Deacon
2018-06-25 10:59 ` [PATCHv2 07/11] atomics: add common header generation files Mark Rutland
2018-06-28 10:58   ` Mark Rutland
2018-06-28 11:46     ` Peter Zijlstra
2018-06-25 10:59 ` [PATCHv2 08/11] atomics: switch to generated fallbacks Mark Rutland
2018-07-04 15:28   ` Will Deacon
2018-07-04 16:01     ` Mark Rutland
2018-07-04 17:44       ` Will Deacon
2018-07-05 11:52         ` Mark Rutland
2018-06-25 10:59 ` [PATCHv2 09/11] atomics: switch to generated atomic-long Mark Rutland
2018-06-25 10:59 ` [PATCHv2 10/11] atomics: switch to generated instrumentation Mark Rutland
2018-06-25 10:59 ` [PATCHv2 11/11] arm64: use instrumented atomics Mark Rutland
2018-07-04 15:24   ` Will Deacon
2018-07-04 16:37     ` Mark Rutland
2018-07-04 17:41       ` Will Deacon
2018-07-05  9:58         ` Mark Rutland
2018-06-25 15:22 ` [PATCHv2 00/11] atomics: generate atomic headers / instrument arm64 Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180625105952.3756-7-mark.rutland@arm.com \
    --to=mark.rutland@arm.com \
    --cc=boqun.feng@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=parri.andrea@gmail.com \
    --cc=peterz@infradead.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®