From: Ian Rogers <irogers@google.com>
To: Arnd Bergmann <arnd@arndb.de>,
Andrii Nakryiko <andrii@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Shuah Khan <shuah@kernel.org>, Kees Cook <keescook@chromium.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Liam Howlett <liam.howlett@oracle.com>,
Miguel Ojeda <ojeda@kernel.org>, Will Deacon <will@kernel.org>,
Mark Brown <broonie@kernel.org>,
David Laight <David.Laight@ACULAB.COM>,
"Michael S. Tsirkin" <mst@redhat.com>,
Shunsuke Mie <mie@igel.co.jp>,
Yafang Shao <laoar.shao@gmail.com>,
Kui-Feng Lee <kuifeng@meta.com>,
James Clark <james.clark@arm.com>,
Nick Forrington <nick.forrington@arm.com>,
Leo Yan <leo.yan@linux.dev>, German Gomez <german.gomez@arm.com>,
Rob Herring <robh@kernel.org>,
John Garry <john.g.garry@oracle.com>,
Sean Christopherson <seanjc@google.com>,
Anup Patel <anup@brainfault.org>, Fuad Tabba <tabba@google.com>,
Andrew Jones <ajones@ventanamicro.com>,
Chao Peng <chao.p.peng@linux.intel.com>,
Haibo Xu <haibo1.xu@intel.com>, Peter Xu <peterx@redhat.com>,
Vishal Annapurve <vannapurve@google.com>,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
bpf@vger.kernel.org, linux-perf-users@vger.kernel.org,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-hardening@vger.kernel.org, llvm@lists.linux.dev
Subject: [PATCH v1 09/13] tools headers: Rewrite linux/atomic.h using C11's stdatomic.h
Date: Sat, 9 Mar 2024 18:05:04 -0800 [thread overview]
Message-ID: <20240310020509.647319-10-irogers@google.com> (raw)
In-Reply-To: <20240310020509.647319-1-irogers@google.com>
Code in tools tries to follow the patterns of the kernel, so the
atomic functions names match. However, having include/linux/atomic.h
in tools complicates building code in tools as assembly and other
functions are necessary - these are often configured in the kernel
using CONFIG options. As tools C code is compiled with the -std=gnu11
flag, it is possible to use stdatomic.h and move the build and other
complications to the compiler/libc.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/arch/x86/include/asm/atomic.h | 84 --------------
tools/include/asm-generic/atomic-gcc.h | 95 ----------------
tools/include/asm/atomic.h | 11 --
tools/include/linux/atomic.h | 107 ++++++++++++++++--
tools/include/linux/types.h | 15 ++-
.../selftests/kvm/include/kvm_util_base.h | 3 +-
6 files changed, 110 insertions(+), 205 deletions(-)
delete mode 100644 tools/arch/x86/include/asm/atomic.h
delete mode 100644 tools/include/asm-generic/atomic-gcc.h
delete mode 100644 tools/include/asm/atomic.h
diff --git a/tools/arch/x86/include/asm/atomic.h b/tools/arch/x86/include/asm/atomic.h
deleted file mode 100644
index 365cf182df12..000000000000
--- a/tools/arch/x86/include/asm/atomic.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _TOOLS_LINUX_ASM_X86_ATOMIC_H
-#define _TOOLS_LINUX_ASM_X86_ATOMIC_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include "rmwcc.h"
-
-#define LOCK_PREFIX "\n\tlock; "
-
-#include <asm/asm.h>
-#include <asm/cmpxchg.h>
-
-/*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- */
-
-#define ATOMIC_INIT(i) { (i) }
-
-/**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
-static inline int atomic_read(const atomic_t *v)
-{
- return READ_ONCE((v)->counter);
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
- v->counter = i;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
- asm volatile(LOCK_PREFIX "incl %0"
- : "+m" (v->counter));
-}
-
-/**
- * atomic_dec_and_test - decrement and test
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
- GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", "e");
-}
-
-static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- return cmpxchg(&v->counter, old, new);
-}
-
-static inline int test_and_set_bit(long nr, unsigned long *addr)
-{
- GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(bts), *addr, "Ir", nr, "%0", "c");
-}
-
-static inline int test_and_clear_bit(long nr, unsigned long *addr)
-{
- GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc), *addr, "Ir", nr, "%0", "c");
-}
-
-#endif /* _TOOLS_LINUX_ASM_X86_ATOMIC_H */
diff --git a/tools/include/asm-generic/atomic-gcc.h b/tools/include/asm-generic/atomic-gcc.h
deleted file mode 100644
index 9b3c528bab92..000000000000
--- a/tools/include/asm-generic/atomic-gcc.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __TOOLS_ASM_GENERIC_ATOMIC_H
-#define __TOOLS_ASM_GENERIC_ATOMIC_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-/*
- * Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
- *
- * Excerpts obtained from the Linux kernel sources.
- */
-
-#define ATOMIC_INIT(i) { (i) }
-
-/**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
-static inline int atomic_read(const atomic_t *v)
-{
- return READ_ONCE((v)->counter);
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
- v->counter = i;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
- __sync_add_and_fetch(&v->counter, 1);
-}
-
-/**
- * atomic_dec_and_test - decrement and test
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
- return __sync_sub_and_fetch(&v->counter, 1) == 0;
-}
-
-#define cmpxchg(ptr, oldval, newval) \
- __sync_val_compare_and_swap(ptr, oldval, newval)
-
-static inline int atomic_cmpxchg(atomic_t *v, int oldval, int newval)
-{
- return cmpxchg(&(v)->counter, oldval, newval);
-}
-
-static inline int test_and_set_bit(long nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- long old;
-
- addr += BIT_WORD(nr);
-
- old = __sync_fetch_and_or(addr, mask);
- return !!(old & mask);
-}
-
-static inline int test_and_clear_bit(long nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- long old;
-
- addr += BIT_WORD(nr);
-
- old = __sync_fetch_and_and(addr, ~mask);
- return !!(old & mask);
-}
-
-#endif /* __TOOLS_ASM_GENERIC_ATOMIC_H */
diff --git a/tools/include/asm/atomic.h b/tools/include/asm/atomic.h
deleted file mode 100644
index 8c9bfffd4191..000000000000
--- a/tools/include/asm/atomic.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __TOOLS_LINUX_ASM_ATOMIC_H
-#define __TOOLS_LINUX_ASM_ATOMIC_H
-
-#if defined(__i386__) || defined(__x86_64__)
-#include "../../arch/x86/include/asm/atomic.h"
-#else
-#include <asm-generic/atomic-gcc.h>
-#endif
-
-#endif /* __TOOLS_LINUX_ASM_ATOMIC_H */
diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
index 01907b33537e..2cf4791ddd5d 100644
--- a/tools/include/linux/atomic.h
+++ b/tools/include/linux/atomic.h
@@ -2,14 +2,107 @@
#ifndef __TOOLS_LINUX_ATOMIC_H
#define __TOOLS_LINUX_ATOMIC_H
-#include <asm/atomic.h>
+#include <stdatomic.h>
+#include <linux/types.h> // For atomic_t
-void atomic_long_set(atomic_long_t *v, long i);
+/*
+ * Reimplementation of the kernel's atomic.h using C11's stdatomic.h to avoid
+ * build logic around compilers, inline assembler, etc.
+ */
-/* atomic_cmpxchg_relaxed */
-#ifndef atomic_cmpxchg_relaxed
-#define atomic_cmpxchg_relaxed atomic_cmpxchg
-#define atomic_cmpxchg_release atomic_cmpxchg
-#endif /* atomic_cmpxchg_relaxed */
+#define ATOMIC_OP(op, c_op) \
+static inline void generic_atomic_##op(int i, atomic_t *v) \
+{ \
+ atomic_fetch_##op(v, i); \
+}
+
+#define ATOMIC_OP_RETURN(op, c_op) \
+static inline int generic_atomic_##op##_return(int i, atomic_t *v) \
+{ \
+ int c = atomic_fetch_##op(v, i); \
+ \
+ return c c_op i; \
+}
+
+#define ATOMIC_FETCH_OP(op, c_op) \
+static inline int generic_atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ return atomic_fetch_##op(v, i); \
+}
+
+static inline int generic_atomic_read(const atomic_t *v)
+{
+ return atomic_load(v);
+}
+
+static inline void generic_atomic_set(atomic_t *v, int i)
+{
+ atomic_store(v, i);
+}
+
+static inline int generic_atomic_cmpxchg_relaxed(atomic_t *v, int old, int new)
+{
+ int expected = old;
+
+ atomic_compare_exchange_weak_explicit(v, &expected, new,
+ memory_order_relaxed, memory_order_relaxed);
+ return expected;
+}
+
+static inline int generic_atomic_cmpxchg_release(atomic_t *v, int old, int new)
+{
+ int expected = old;
+
+ /*
+ * Note, the stricter memory_order_seq_cst is used as
+ * memory_order_release fails with an invalid-memory-model error.
+ */
+ atomic_compare_exchange_weak_explicit(v, &expected, new,
+ memory_order_seq_cst, memory_order_seq_cst);
+ return expected;
+}
+
+ATOMIC_OP_RETURN(add, +)
+ATOMIC_OP_RETURN(sub, -)
+
+ATOMIC_FETCH_OP(add, +)
+ATOMIC_FETCH_OP(sub, -)
+ATOMIC_FETCH_OP(and, &)
+ATOMIC_FETCH_OP(or, |)
+ATOMIC_FETCH_OP(xor, ^)
+
+ATOMIC_OP(add, +)
+ATOMIC_OP(sub, -)
+ATOMIC_OP(and, &)
+ATOMIC_OP(or, |)
+ATOMIC_OP(xor, ^)
+
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+
+#define arch_atomic_add_return generic_atomic_add_return
+#define arch_atomic_sub_return generic_atomic_sub_return
+
+#define arch_atomic_fetch_add generic_atomic_fetch_add
+#define arch_atomic_fetch_sub generic_atomic_fetch_sub
+#define arch_atomic_fetch_and generic_atomic_fetch_and
+#define arch_atomic_fetch_or generic_atomic_fetch_or
+#define arch_atomic_fetch_xor generic_atomic_fetch_xor
+
+#define arch_atomic_add generic_atomic_add
+#define arch_atomic_sub generic_atomic_sub
+#define arch_atomic_and generic_atomic_and
+#define arch_atomic_or generic_atomic_or
+#define arch_atomic_xor generic_atomic_xor
+
+#define arch_atomic_read(v) generic_atomic_read(v)
+#define arch_atomic_set(v, i) generic_atomic_set(v, i)
+#define atomic_set(v, i) generic_atomic_set(v, i)
+#define atomic_read(v) generic_atomic_read(v)
+#define atomic_cmpxchg_relaxed(v, o, n) generic_atomic_cmpxchg_relaxed(v, o, n)
+#define atomic_cmpxchg_release(v, o, n) generic_atomic_cmpxchg_release(v, o, n)
+#define atomic_inc(v) generic_atomic_add(1, v)
+#define atomic_dec(v) generic_atomic_sub(1, v)
#endif /* __TOOLS_LINUX_ATOMIC_H */
diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h
index 8519386acd23..cb1f44f1ed5e 100644
--- a/tools/include/linux/types.h
+++ b/tools/include/linux/types.h
@@ -74,13 +74,16 @@ typedef u64 phys_addr_t;
typedef u32 phys_addr_t;
#endif
-typedef struct {
- int counter;
-} atomic_t;
+#ifndef __cplusplus
+/* C++17 doesn't support stdatomic.h but C++23 does. */
+#include <stdatomic.h>
-typedef struct {
- long counter;
-} atomic_long_t;
+typedef atomic_int atomic_t;
+
+#define ATOMIC_INIT(i) (i)
+
+typedef atomic_long atomic_long_t;
+#endif
#ifndef __aligned_u64
# define __aligned_u64 __u64 __attribute__((aligned(8)))
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 9e5afc472c14..7c81da425abc 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -9,6 +9,7 @@
#include "test_util.h"
+#include <linux/atomic.h>
#include <linux/compiler.h>
#include "linux/hashtable.h"
#include "linux/list.h"
@@ -17,8 +18,6 @@
#include "linux/rbtree.h"
#include <linux/types.h>
-#include <asm/atomic.h>
-
#include <sys/ioctl.h>
#include "sparsebit.h"
--
2.44.0.278.ge034bb2e1d-goog
next prev parent reply other threads:[~2024-03-10 2:05 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-10 2:04 [PATCH v1 00/13] tools header compiler.h update Ian Rogers
2024-03-10 2:04 ` [PATCH v1 01/13] tools bpf: Synchronize bpf.h with kernel uapi version Ian Rogers
2024-03-10 2:04 ` [PATCH v1 02/13] libbpf: Make __printf define conditional Ian Rogers
2024-03-11 17:49 ` Andrii Nakryiko
2024-03-11 18:54 ` Ian Rogers
2024-03-11 20:51 ` Andrii Nakryiko
2024-03-10 2:04 ` [PATCH v1 03/13] libperf xyarray: Use correct stddef.h include Ian Rogers
2024-03-10 2:04 ` [PATCH v1 04/13] perf expr: Add missing stdbool.h include Ian Rogers
2024-03-10 2:05 ` [PATCH v1 05/13] perf expr: Tidy up header guard Ian Rogers
2024-03-10 2:05 ` [PATCH v1 06/13] perf debug: Add missing linux/types.h include Ian Rogers
2024-03-10 2:05 ` [PATCH v1 07/13] perf cacheline: " Ian Rogers
2024-03-10 2:05 ` [PATCH v1 08/13] perf arm-spe: " Ian Rogers
2024-03-10 2:05 ` Ian Rogers [this message]
2024-03-10 2:05 ` [PATCH v1 10/13] asm-generic: Avoid transitive dependency for unaligned.h Ian Rogers
2024-03-10 2:05 ` [PATCH v1 11/13] tools headers: Sync linux/overflow.h Ian Rogers
2024-03-10 2:05 ` [PATCH v1 12/13] tools headers: Sync compiler.h headers Ian Rogers
2024-03-10 11:45 ` Miguel Ojeda
2024-03-11 16:34 ` James Clark
2024-03-11 19:24 ` Ian Rogers
2024-03-11 19:58 ` Arnaldo Carvalho de Melo
2024-03-10 2:05 ` [PATCH v1 13/13] tools headers: Rename noinline to __noinline Ian Rogers
2024-03-10 11:24 ` Miguel Ojeda
2024-03-11 15:33 ` Nick Desaulniers
2024-03-11 15:43 ` Michael S. Tsirkin
2024-03-11 16:21 ` Nick Desaulniers
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=20240310020509.647319-10-irogers@google.com \
--to=irogers@google.com \
--cc=David.Laight@ACULAB.COM \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ajones@ventanamicro.com \
--cc=akpm@linux-foundation.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=andrii@kernel.org \
--cc=anup@brainfault.org \
--cc=arnd@arndb.de \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=broonie@kernel.org \
--cc=chao.p.peng@linux.intel.com \
--cc=daniel@iogearbox.net \
--cc=german.gomez@arm.com \
--cc=gustavoars@kernel.org \
--cc=haibo1.xu@intel.com \
--cc=haoluo@google.com \
--cc=james.clark@arm.com \
--cc=john.fastabend@gmail.com \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=justinstitt@google.com \
--cc=keescook@chromium.org \
--cc=kpsingh@kernel.org \
--cc=kuifeng@meta.com \
--cc=kvm@vger.kernel.org \
--cc=laoar.shao@gmail.com \
--cc=leo.yan@linux.dev \
--cc=liam.howlett@oracle.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mark.rutland@arm.com \
--cc=martin.lau@linux.dev \
--cc=mie@igel.co.jp \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=mst@redhat.com \
--cc=namhyung@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=nick.forrington@arm.com \
--cc=ojeda@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=peterz@infradead.org \
--cc=robh@kernel.org \
--cc=sdf@google.com \
--cc=seanjc@google.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=tabba@google.com \
--cc=vannapurve@google.com \
--cc=will@kernel.org \
--cc=yonghong.song@linux.dev \
/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;
as well as URLs for NNTP newsgroup(s).