From: Will Deacon <will@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Will Deacon <will@kernel.org>, Yunjae Lee <lyj7694@gmail.com>,
SeongJae Park <sj38.park@gmail.com>,
"Paul E. McKenney" <paulmck@kernel.org>,
Josh Triplett <josh@joshtriplett.org>,
Matt Turner <mattst88@gmail.com>,
Ivan Kokshaysky <ink@jurassic.park.msu.ru>,
Richard Henderson <rth@twiddle.net>,
Peter Zijlstra <peterz@infradead.org>,
Alan Stern <stern@rowland.harvard.edu>,
Michael Ellerman <mpe@ellerman.id.au>,
"Michael S. Tsirkin" <mst@redhat.com>,
Jason Wang <jasowang@redhat.com>, Arnd Bergmann <arnd@arndb.de>,
Joe Perches <joe@perches.com>, Boqun Feng <boqun.feng@gmail.com>,
linux-alpha@vger.kernel.org,
virtualization@lists.linux-foundation.org
Subject: [PATCH 01/13] compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h
Date: Fri, 8 Nov 2019 17:01:08 +0000 [thread overview]
Message-ID: <20191108170120.22331-2-will@kernel.org> (raw)
In-Reply-To: <20191108170120.22331-1-will@kernel.org>
In preparation for allowing architectures to define their own
implementation of the 'READ_ONCE()' macro, move the generic
'{READ,WRITE}_ONCE()' definitions out of the unwieldy 'linux/compiler.h'
and into a new 'rwonce.h' header under 'asm-generic'.
Signed-off-by: Will Deacon <will@kernel.org>
---
include/asm-generic/Kbuild | 1 +
include/asm-generic/rwonce.h | 110 +++++++++++++++++++++++++++
include/linux/compiler.h | 114 +---------------------------
include/linux/compiler_attributes.h | 12 +++
4 files changed, 125 insertions(+), 112 deletions(-)
create mode 100644 include/asm-generic/rwonce.h
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index adff14fcb8e4..2a7a1e94d4cb 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -4,4 +4,5 @@
# (This file is not included when SRCARCH=um since UML borrows several
# asm headers from the host architecutre.)
+mandatory-y += rwonce.h
mandatory-y += simd.h
diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
new file mode 100644
index 000000000000..d189455ae038
--- /dev/null
+++ b/include/asm-generic/rwonce.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Prevent the compiler from merging or refetching reads or writes. The
+ * compiler is also forbidden from reordering successive instances of
+ * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
+ * particular ordering. One way to make the compiler aware of ordering is to
+ * put the two invocations of READ_ONCE or WRITE_ONCE in different C
+ * statements.
+ *
+ * These two macros will also work on aggregate data types like structs or
+ * unions. If the size of the accessed data type exceeds the word size of
+ * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
+ * fall back to memcpy(). There's at least two memcpy()s: one for the
+ * __builtin_memcpy() and then one for the macro doing the copy of variable
+ * - '__u' allocated on the stack.
+ *
+ * Their two major use cases are: (1) Mediating communication between
+ * process-level code and irq/NMI handlers, all running on the same CPU,
+ * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
+ * mutilate accesses that either do not require ordering or that interact
+ * with an explicit memory barrier or atomic instruction that provides the
+ * required ordering.
+ */
+#ifndef __ASM_GENERIC_RWONCE_H
+#define __ASM_GENERIC_RWONCE_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler_attributes.h>
+#include <linux/kasan-checks.h>
+
+#include <uapi/linux/types.h>
+
+#include <asm/barrier.h>
+
+#define __READ_ONCE_SIZE \
+({ \
+ switch (size) { \
+ case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \
+ case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \
+ case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \
+ case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \
+ default: \
+ barrier(); \
+ __builtin_memcpy((void *)res, (const void *)p, size); \
+ barrier(); \
+ } \
+})
+
+static __always_inline
+void __read_once_size(const volatile void *p, void *res, int size)
+{
+ __READ_ONCE_SIZE;
+}
+
+static __no_kasan_or_inline
+void __read_once_size_nocheck(const volatile void *p, void *res, int size)
+{
+ __READ_ONCE_SIZE;
+}
+
+static __always_inline void __write_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
+ case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
+ case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
+ case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
+ default:
+ barrier();
+ __builtin_memcpy((void *)p, (const void *)res, size);
+ barrier();
+ }
+}
+
+#define __READ_ONCE(x, check) \
+({ \
+ union { typeof(x) __val; char __c[1]; } __u; \
+ if (check) \
+ __read_once_size(&(x), __u.__c, sizeof(x)); \
+ else \
+ __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
+ smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
+ __u.__val; \
+})
+#define READ_ONCE(x) __READ_ONCE(x, 1)
+
+/*
+ * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
+ * to hide memory access from KASAN.
+ */
+#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
+
+static __no_kasan_or_inline
+unsigned long read_word_at_a_time(const void *addr)
+{
+ kasan_check_read(addr, 1);
+ return *(unsigned long *)addr;
+}
+
+#define WRITE_ONCE(x, val) \
+({ \
+ union { typeof(x) __val; char __c[1]; } __u = \
+ { .__val = (__force typeof(x)) (val) }; \
+ __write_once_size(&(x), __u.__c, sizeof(x)); \
+ __u.__val; \
+})
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_GENERIC_RWONCE_H */
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 5e88e7e33abe..6de09d2f42ad 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -177,118 +177,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
#endif
-#include <uapi/linux/types.h>
-
-#define __READ_ONCE_SIZE \
-({ \
- switch (size) { \
- case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \
- case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \
- case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \
- case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \
- default: \
- barrier(); \
- __builtin_memcpy((void *)res, (const void *)p, size); \
- barrier(); \
- } \
-})
-
-static __always_inline
-void __read_once_size(const volatile void *p, void *res, int size)
-{
- __READ_ONCE_SIZE;
-}
-
-#ifdef CONFIG_KASAN
-/*
- * We can't declare function 'inline' because __no_sanitize_address confilcts
- * with inlining. Attempt to inline it may cause a build failure.
- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
- * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
- */
-# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
-#else
-# define __no_kasan_or_inline __always_inline
-#endif
-
-static __no_kasan_or_inline
-void __read_once_size_nocheck(const volatile void *p, void *res, int size)
-{
- __READ_ONCE_SIZE;
-}
-
-static __always_inline void __write_once_size(volatile void *p, void *res, int size)
-{
- switch (size) {
- case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
- case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
- case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
- case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
- default:
- barrier();
- __builtin_memcpy((void *)p, (const void *)res, size);
- barrier();
- }
-}
-
-/*
- * Prevent the compiler from merging or refetching reads or writes. The
- * compiler is also forbidden from reordering successive instances of
- * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
- * particular ordering. One way to make the compiler aware of ordering is to
- * put the two invocations of READ_ONCE or WRITE_ONCE in different C
- * statements.
- *
- * These two macros will also work on aggregate data types like structs or
- * unions. If the size of the accessed data type exceeds the word size of
- * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
- * fall back to memcpy(). There's at least two memcpy()s: one for the
- * __builtin_memcpy() and then one for the macro doing the copy of variable
- * - '__u' allocated on the stack.
- *
- * Their two major use cases are: (1) Mediating communication between
- * process-level code and irq/NMI handlers, all running on the same CPU,
- * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
- * mutilate accesses that either do not require ordering or that interact
- * with an explicit memory barrier or atomic instruction that provides the
- * required ordering.
- */
-#include <asm/barrier.h>
-#include <linux/kasan-checks.h>
-
-#define __READ_ONCE(x, check) \
-({ \
- union { typeof(x) __val; char __c[1]; } __u; \
- if (check) \
- __read_once_size(&(x), __u.__c, sizeof(x)); \
- else \
- __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
- smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
- __u.__val; \
-})
-#define READ_ONCE(x) __READ_ONCE(x, 1)
-
-/*
- * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
- * to hide memory access from KASAN.
- */
-#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
-
-static __no_kasan_or_inline
-unsigned long read_word_at_a_time(const void *addr)
-{
- kasan_check_read(addr, 1);
- return *(unsigned long *)addr;
-}
-
-#define WRITE_ONCE(x, val) \
-({ \
- union { typeof(x) __val; char __c[1]; } __u = \
- { .__val = (__force typeof(x)) (val) }; \
- __write_once_size(&(x), __u.__c, sizeof(x)); \
- __u.__val; \
-})
-
#endif /* __KERNEL__ */
/*
@@ -356,4 +244,6 @@ static inline void *offset_to_ptr(const int *off)
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
+#include <asm/rwonce.h>
+
#endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
index cdf016596659..7cb92286de9f 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -270,4 +270,16 @@
*/
#define __weak __attribute__((__weak__))
+#ifdef CONFIG_KASAN
+/*
+ * We can't declare function 'inline' because __no_sanitize_address confilcts
+ * with inlining. Attempt to inline it may cause a build failure.
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
+ * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
+ */
+# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
+#else
+# define __no_kasan_or_inline __always_inline
+#endif
+
#endif /* __LINUX_COMPILER_ATTRIBUTES_H */
--
2.24.0.rc1.363.gb1bccd3e3d-goog
next prev parent reply other threads:[~2019-11-08 17:01 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-08 17:01 [PATCH 00/13] Finish off [smp_]read_barrier_depends() Will Deacon
2019-11-08 17:01 ` Will Deacon [this message]
2019-11-08 19:57 ` [PATCH 01/13] compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h Arnd Bergmann
2019-11-08 19:57 ` Arnd Bergmann
2019-11-11 8:10 ` [PATCH 01/13] compiler.h: Split {READ, WRITE}_ONCE " Christian Borntraeger
2019-11-11 8:10 ` [PATCH 01/13] compiler.h: Split {READ,WRITE}_ONCE " Christian Borntraeger
2019-11-11 8:10 ` Christian Borntraeger
2019-11-11 9:32 ` [PATCH 01/13] compiler.h: Split {READ, WRITE}_ONCE " Arnd Bergmann
2019-11-11 9:32 ` [PATCH 01/13] compiler.h: Split {READ,WRITE}_ONCE " Arnd Bergmann
2019-11-11 9:32 ` [PATCH 01/13] compiler.h: Split {READ, WRITE}_ONCE " Arnd Bergmann
2019-11-12 11:36 ` [PATCH 01/13] compiler.h: Split {READ,WRITE}_ONCE " Will Deacon
2019-11-12 11:36 ` Will Deacon
2019-11-08 19:57 ` [PATCH 01/13] compiler.h: Split {READ, WRITE}_ONCE " Arnd Bergmann
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 02/13] READ_ONCE: Undefine internal __READ_ONCE_SIZE macro after use Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 03/13] READ_ONCE: Allow __READ_ONCE_SIZE cases to be overridden by the architecture Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 04/13] vhost: Remove redundant use of read_barrier_depends() barrier Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 05/13] alpha: Override READ_ONCE() with barriered implementation Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 06/13] READ_ONCE: Remove smp_read_barrier_depends() invocation Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 07/13] alpha: Replace smp_read_barrier_depends() usage with smp_[r]mb() Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 08/13] locking/barriers: Remove definitions for [smp_]read_barrier_depends() Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 09/13] Documentation/barriers: Remove references to [smp_]read_barrier_depends() Will Deacon
2019-11-21 19:32 ` [PATCH] Documentation/barriers/kokr: " SeongJae Park
2019-11-26 22:20 ` Paul E. McKenney
2019-11-29 18:08 ` [PATCH v2] " SeongJae Park
2019-12-06 17:20 ` SeongJae Park
2019-12-06 20:44 ` Paul E. McKenney
2019-12-06 21:29 ` SeongJae Park
2019-12-06 22:08 ` Paul E. McKenney
2019-12-06 22:38 ` SeongJae Park
2019-12-06 22:51 ` Paul E. McKenney
2019-12-09 9:44 ` Will Deacon
2019-12-09 17:00 ` Paul E. McKenney
2019-12-09 17:06 ` Will Deacon
2019-12-09 17:43 ` SeongJae Park
2019-11-08 17:01 ` [PATCH 09/13] Documentation/barriers: " Will Deacon
2019-11-08 17:01 ` [PATCH 10/13] tools/memory-model: Remove smp_read_barrier_depends() from informal doc Will Deacon
2019-11-08 17:42 ` Alan Stern
2019-11-08 17:42 ` Alan Stern
2019-11-08 17:42 ` Alan Stern
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 11/13] powerpc: Remove comment about read_barrier_depends() Will Deacon
2019-11-20 10:37 ` Michael Ellerman
2019-11-26 22:24 ` Paul E. McKenney
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 12/13] include/linux: Remove smp_read_barrier_depends() from comments Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 17:01 ` [PATCH 13/13] checkpatch: Remove checks relating to [smp_]read_barrier_depends() Will Deacon
2019-11-08 17:01 ` Will Deacon
2019-11-08 18:50 ` [PATCH 00/13] Finish off [smp_]read_barrier_depends() Paul E. McKenney
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=20191108170120.22331-2-will@kernel.org \
--to=will@kernel.org \
--cc=arnd@arndb.de \
--cc=boqun.feng@gmail.com \
--cc=ink@jurassic.park.msu.ru \
--cc=jasowang@redhat.com \
--cc=joe@perches.com \
--cc=josh@joshtriplett.org \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lyj7694@gmail.com \
--cc=mattst88@gmail.com \
--cc=mpe@ellerman.id.au \
--cc=mst@redhat.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rth@twiddle.net \
--cc=sj38.park@gmail.com \
--cc=stern@rowland.harvard.edu \
--cc=virtualization@lists.linux-foundation.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.