Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1611173 > unrolled thread
| Started by | Dmitry Vyukov <dvyukov@google.com> |
|---|---|
| First post | 2017-03-28 18:20 +0200 |
| Last post | 2017-03-30 12:50 +0200 |
| Articles | 7 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 4/8] asm-generic: add atomic-instrumented.h Dmitry Vyukov <dvyukov@google.com> - 2017-03-28 18:20 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Matthew Wilcox <willy@infradead.org> - 2017-03-28 23:40 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Dmitry Vyukov <dvyukov@google.com> - 2017-03-29 10:30 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Mark Rutland <mark.rutland@arm.com> - 2017-03-29 15:30 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Mark Rutland <mark.rutland@arm.com> - 2017-03-29 19:20 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Ingo Molnar <mingo@kernel.org> - 2017-03-30 08:50 +0200
Re: [PATCH 4/8] asm-generic: add atomic-instrumented.h Mark Rutland <mark.rutland@arm.com> - 2017-03-30 12:50 +0200
| From | Dmitry Vyukov <dvyukov@google.com> |
|---|---|
| Date | 2017-03-28 18:20 +0200 |
| Subject | [PATCH 4/8] asm-generic: add atomic-instrumented.h |
| Message-ID | <tq20H-1Mi-49@gated-at.bofh.it> |
The new header allows to wrap per-arch atomic operations
and add common functionality to all of them.
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: kasan-dev@googlegroups.com
Cc: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org
Cc: x86@kernel.org
---
include/asm-generic/atomic-instrumented.h | 319 ++++++++++++++++++++++++++++++
1 file changed, 319 insertions(+)
diff --git a/include/asm-generic/atomic-instrumented.h b/include/asm-generic/atomic-instrumented.h
new file mode 100644
index 000000000000..fd483115d4c6
--- /dev/null
+++ b/include/asm-generic/atomic-instrumented.h
@@ -0,0 +1,319 @@
+#ifndef _LINUX_ATOMIC_INSTRUMENTED_H
+#define _LINUX_ATOMIC_INSTRUMENTED_H
+
+static __always_inline int atomic_read(const atomic_t *v)
+{
+ return arch_atomic_read(v);
+}
+
+static __always_inline long long atomic64_read(const atomic64_t *v)
+{
+ return arch_atomic64_read(v);
+}
+
+static __always_inline void atomic_set(atomic_t *v, int i)
+{
+ arch_atomic_set(v, i);
+}
+
+static __always_inline void atomic64_set(atomic64_t *v, long long i)
+{
+ arch_atomic64_set(v, i);
+}
+
+static __always_inline int atomic_xchg(atomic_t *v, int i)
+{
+ return arch_atomic_xchg(v, i);
+}
+
+static __always_inline long long atomic64_xchg(atomic64_t *v, long long i)
+{
+ return arch_atomic64_xchg(v, i);
+}
+
+static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ return arch_atomic_cmpxchg(v, old, new);
+}
+
+static __always_inline long long atomic64_cmpxchg(atomic64_t *v, long long old,
+ long long new)
+{
+ return arch_atomic64_cmpxchg(v, old, new);
+}
+
+#ifdef arch_atomic_try_cmpxchg
+#define atomic_try_cmpxchg atomic_try_cmpxchg
+static __always_inline bool atomic_try_cmpxchg(atomic_t *v, int *old, int new)
+{
+ return arch_atomic_try_cmpxchg(v, old, new);
+}
+#endif
+
+#ifdef arch_atomic64_try_cmpxchg
+#define atomic64_try_cmpxchg atomic64_try_cmpxchg
+static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, long long *old,
+ long long new)
+{
+ return arch_atomic64_try_cmpxchg(v, old, new);
+}
+#endif
+
+static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+ return __arch_atomic_add_unless(v, a, u);
+}
+
+
+static __always_inline bool atomic64_add_unless(atomic64_t *v, long long a,
+ long long u)
+{
+ return arch_atomic64_add_unless(v, a, u);
+}
+
+static __always_inline void atomic_inc(atomic_t *v)
+{
+ arch_atomic_inc(v);
+}
+
+static __always_inline void atomic64_inc(atomic64_t *v)
+{
+ arch_atomic64_inc(v);
+}
+
+static __always_inline void atomic_dec(atomic_t *v)
+{
+ arch_atomic_dec(v);
+}
+
+static __always_inline void atomic64_dec(atomic64_t *v)
+{
+ arch_atomic64_dec(v);
+}
+
+static __always_inline void atomic_add(int i, atomic_t *v)
+{
+ arch_atomic_add(i, v);
+}
+
+static __always_inline void atomic64_add(long long i, atomic64_t *v)
+{
+ arch_atomic64_add(i, v);
+}
+
+static __always_inline void atomic_sub(int i, atomic_t *v)
+{
+ arch_atomic_sub(i, v);
+}
+
+static __always_inline void atomic64_sub(long long i, atomic64_t *v)
+{
+ arch_atomic64_sub(i, v);
+}
+
+static __always_inline void atomic_and(int i, atomic_t *v)
+{
+ arch_atomic_and(i, v);
+}
+
+static __always_inline void atomic64_and(long long i, atomic64_t *v)
+{
+ arch_atomic64_and(i, v);
+}
+
+static __always_inline void atomic_or(int i, atomic_t *v)
+{
+ arch_atomic_or(i, v);
+}
+
+static __always_inline void atomic64_or(long long i, atomic64_t *v)
+{
+ arch_atomic64_or(i, v);
+}
+
+static __always_inline void atomic_xor(int i, atomic_t *v)
+{
+ arch_atomic_xor(i, v);
+}
+
+static __always_inline void atomic64_xor(long long i, atomic64_t *v)
+{
+ arch_atomic64_xor(i, v);
+}
+
+static __always_inline int atomic_inc_return(atomic_t *v)
+{
+ return arch_atomic_inc_return(v);
+}
+
+static __always_inline long long atomic64_inc_return(atomic64_t *v)
+{
+ return arch_atomic64_inc_return(v);
+}
+
+static __always_inline int atomic_dec_return(atomic_t *v)
+{
+ return arch_atomic_dec_return(v);
+}
+
+static __always_inline long long atomic64_dec_return(atomic64_t *v)
+{
+ return arch_atomic64_dec_return(v);
+}
+
+static __always_inline long long atomic64_inc_not_zero(atomic64_t *v)
+{
+ return arch_atomic64_inc_not_zero(v);
+}
+
+static __always_inline long long atomic64_dec_if_positive(atomic64_t *v)
+{
+ return arch_atomic64_dec_if_positive(v);
+}
+
+static __always_inline bool atomic_dec_and_test(atomic_t *v)
+{
+ return arch_atomic_dec_and_test(v);
+}
+
+static __always_inline bool atomic64_dec_and_test(atomic64_t *v)
+{
+ return arch_atomic64_dec_and_test(v);
+}
+
+static __always_inline bool atomic_inc_and_test(atomic_t *v)
+{
+ return arch_atomic_inc_and_test(v);
+}
+
+static __always_inline bool atomic64_inc_and_test(atomic64_t *v)
+{
+ return arch_atomic64_inc_and_test(v);
+}
+
+static __always_inline int atomic_add_return(int i, atomic_t *v)
+{
+ return arch_atomic_add_return(i, v);
+}
+
+static __always_inline long long atomic64_add_return(long long i, atomic64_t *v)
+{
+ return arch_atomic64_add_return(i, v);
+}
+
+static __always_inline int atomic_sub_return(int i, atomic_t *v)
+{
+ return arch_atomic_sub_return(i, v);
+}
+
+static __always_inline long long atomic64_sub_return(long long i, atomic64_t *v)
+{
+ return arch_atomic64_sub_return(i, v);
+}
+
+static __always_inline int atomic_fetch_add(int i, atomic_t *v)
+{
+ return arch_atomic_fetch_add(i, v);
+}
+
+static __always_inline long long atomic64_fetch_add(long long i, atomic64_t *v)
+{
+ return arch_atomic64_fetch_add(i, v);
+}
+
+static __always_inline int atomic_fetch_sub(int i, atomic_t *v)
+{
+ return arch_atomic_fetch_sub(i, v);
+}
+
+static __always_inline long long atomic64_fetch_sub(long long i, atomic64_t *v)
+{
+ return arch_atomic64_fetch_sub(i, v);
+}
+
+static __always_inline int atomic_fetch_and(int i, atomic_t *v)
+{
+ return arch_atomic_fetch_and(i, v);
+}
+
+static __always_inline long long atomic64_fetch_and(long long i, atomic64_t *v)
+{
+ return arch_atomic64_fetch_and(i, v);
+}
+
+static __always_inline int atomic_fetch_or(int i, atomic_t *v)
+{
+ return arch_atomic_fetch_or(i, v);
+}
+
+static __always_inline long long atomic64_fetch_or(long long i, atomic64_t *v)
+{
+ return arch_atomic64_fetch_or(i, v);
+}
+
+static __always_inline int atomic_fetch_xor(int i, atomic_t *v)
+{
+ return arch_atomic_fetch_xor(i, v);
+}
+
+static __always_inline long long atomic64_fetch_xor(long long i, atomic64_t *v)
+{
+ return arch_atomic64_fetch_xor(i, v);
+}
+
+static __always_inline bool atomic_sub_and_test(int i, atomic_t *v)
+{
+ return arch_atomic_sub_and_test(i, v);
+}
+
+static __always_inline bool atomic64_sub_and_test(long long i, atomic64_t *v)
+{
+ return arch_atomic64_sub_and_test(i, v);
+}
+
+static __always_inline bool atomic_add_negative(int i, atomic_t *v)
+{
+ return arch_atomic_add_negative(i, v);
+}
+
+static __always_inline bool atomic64_add_negative(long long i, atomic64_t *v)
+{
+ return arch_atomic64_add_negative(i, v);
+}
+
+#define cmpxchg(ptr, old, new) \
+({ \
+ arch_cmpxchg((ptr), (old), (new)); \
+})
+
+#define sync_cmpxchg(ptr, old, new) \
+({ \
+ arch_sync_cmpxchg((ptr), (old), (new)); \
+})
+
+#define cmpxchg_local(ptr, old, new) \
+({ \
+ arch_cmpxchg_local((ptr), (old), (new)); \
+})
+
+#define cmpxchg64(ptr, old, new) \
+({ \
+ arch_cmpxchg64((ptr), (old), (new)); \
+})
+
+#define cmpxchg64_local(ptr, old, new) \
+({ \
+ arch_cmpxchg64_local((ptr), (old), (new)); \
+})
+
+#define cmpxchg_double(p1, p2, o1, o2, n1, n2) \
+({ \
+ arch_cmpxchg_double((p1), (p2), (o1), (o2), (n1), (n2)); \
+})
+
+#define cmpxchg_double_local(p1, p2, o1, o2, n1, n2) \
+({ \
+ arch_cmpxchg_double_local((p1), (p2), (o1), (o2), (n1), (n2)); \
+})
+
+#endif /* _LINUX_ATOMIC_INSTRUMENTED_H */
--
2.12.2.564.g063fe858b8-goog
[toc] | [next] | [standalone]
| From | Matthew Wilcox <willy@infradead.org> |
|---|---|
| Date | 2017-03-28 23:40 +0200 |
| Message-ID | <tq70n-5jM-37@gated-at.bofh.it> |
| In reply to | #1611173 |
On Tue, Mar 28, 2017 at 06:15:41PM +0200, Dmitry Vyukov wrote: > The new header allows to wrap per-arch atomic operations > and add common functionality to all of them. Why a new header instead of putting this in linux/atomic.h?
[toc] | [prev] | [next] | [standalone]
| From | Dmitry Vyukov <dvyukov@google.com> |
|---|---|
| Date | 2017-03-29 10:30 +0200 |
| Message-ID | <tqh9n-4cT-1@gated-at.bofh.it> |
| In reply to | #1611385 |
On Tue, Mar 28, 2017 at 11:35 PM, Matthew Wilcox <willy@infradead.org> wrote: > On Tue, Mar 28, 2017 at 06:15:41PM +0200, Dmitry Vyukov wrote: >> The new header allows to wrap per-arch atomic operations >> and add common functionality to all of them. > > Why a new header instead of putting this in linux/atomic.h? Only a subset of archs include this header. If we pre-include it for all arches without changing their atomic.h, we will break build. We of course play some tricks with preprocessor. It's also large enough to put into a separate header IMO. Also a reasonable question: why put it into linux/atomic.h instead of a new header? :)
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2017-03-29 15:30 +0200 |
| Message-ID | <tqlPI-7sg-25@gated-at.bofh.it> |
| In reply to | #1611385 |
On Tue, Mar 28, 2017 at 02:35:13PM -0700, Matthew Wilcox wrote:
> On Tue, Mar 28, 2017 at 06:15:41PM +0200, Dmitry Vyukov wrote:
> > The new header allows to wrap per-arch atomic operations
> > and add common functionality to all of them.
>
> Why a new header instead of putting this in linux/atomic.h?
The idea was that doing it this way allowed architectures to switch over
to the arch_* naming without a flag day. Currently this only matters for
KASAN, which is only supported by a couple of architectures (arm64,
x86).
I seem to recall that there was an issue that prevented us from solving
this with ifdeffery early in linux/atomic.h like:
#ifdef arch_op
#define op(...) ({ \
kasna_whatever(...) \
arch_op(...) \
})
#endif
... but I can't recall specifically what it was.
Thanks,
Mark.
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2017-03-29 19:20 +0200 |
| Message-ID | <tqpqj-1xr-25@gated-at.bofh.it> |
| In reply to | #1611173 |
Hi,
On Tue, Mar 28, 2017 at 06:15:41PM +0200, Dmitry Vyukov wrote:
> The new header allows to wrap per-arch atomic operations
> and add common functionality to all of them.
I had a quick look at what it would take to have arm64 use this, and I
have a couple of thoughts.
> +static __always_inline int atomic_xchg(atomic_t *v, int i)
> +{
> + return arch_atomic_xchg(v, i);
> +}
I generally agree that avoiding several layers of CPP aids readability
here, and as-is I think this is fine.
However, avoiding CPP entirely will mean that the file becomes painfully
verbose when support for {relaxed,acquire,release}-order variants is
added.
Just considering atomic_xchg{,_relaxed,_acquire,_release}(), for
example:
----
static __always_inline int atomic_xchg(atomic_t *v, int i)
{
kasan_check_write(v, sizeof(*v));
return arch_atomic_xchg(v, i);
}
#ifdef arch_atomic_xchg_relaxed
static __always_inline int atomic_xchg(atomic_t *v, int i)
{
kasan_check_write(v, sizeof(*v));
return arch_atomic_xchg_relaxed(v, i);
}
#define atomic_xchg_relaxed atomic_xchg_relaxed
#endif
#ifdef arch_atomic_xchg_acquire
static __always_inline int atomic_xchg(atomic_t *v, int i)
{
kasan_check_write(v, sizeof(*v));
return arch_atomic_xchg_acquire(v, i);
}
#define atomic_xchg_acquire atomic_xchg_acquire
#endif
#ifdef arch_atomic_xchg_release
static __always_inline int atomic_xchg(atomic_t *v, int i)
{
kasan_check_write(v, sizeof(*v));
return arch_atomic_xchg_release(v, i);
}
#define atomic_xchg_release atomic_xchg_release
#endif
----
With some minimal CPP, it can be a lot more manageable:
----
#define INSTR_ATOMIC_XCHG(order) \
static __always_inline int atomic_xchg##order(atomic_t *v, int i) \
{ \
kasan_check_write(v, sizeof(*v)); \
arch_atomic_xchg##order(v, i); \
}
#define INSTR_ATOMIC_XCHG()
#ifdef arch_atomic_xchg_relaxed
INSTR_ATOMIC_XCHG(_relaxed)
#define atomic_xchg_relaxed atomic_xchg_relaxed
#endif
#ifdef arch_atomic_xchg_acquire
INSTR_ATOMIC_XCHG(_acquire)
#define atomic_xchg_acquire atomic_xchg_acquire
#endif
#ifdef arch_atomic_xchg_relaxed
INSTR_ATOMIC_XCHG(_relaxed)
#define atomic_xchg_relaxed atomic_xchg_relaxed
#endif
----
Is there any objection to some light CPP usage as above for adding the
{relaxed,acquire,release} variants?
Thanks,
Mark.
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2017-03-30 08:50 +0200 |
| Message-ID | <tqC4a-2hn-33@gated-at.bofh.it> |
| In reply to | #1612168 |
* Mark Rutland <mark.rutland@arm.com> wrote:
> With some minimal CPP, it can be a lot more manageable:
>
> ----
> #define INSTR_ATOMIC_XCHG(order) \
> static __always_inline int atomic_xchg##order(atomic_t *v, int i) \
> { \
> kasan_check_write(v, sizeof(*v)); \
> arch_atomic_xchg##order(v, i); \
> }
>
> #define INSTR_ATOMIC_XCHG()
>
> #ifdef arch_atomic_xchg_relaxed
> INSTR_ATOMIC_XCHG(_relaxed)
> #define atomic_xchg_relaxed atomic_xchg_relaxed
> #endif
>
> #ifdef arch_atomic_xchg_acquire
> INSTR_ATOMIC_XCHG(_acquire)
> #define atomic_xchg_acquire atomic_xchg_acquire
> #endif
>
> #ifdef arch_atomic_xchg_relaxed
> INSTR_ATOMIC_XCHG(_relaxed)
> #define atomic_xchg_relaxed atomic_xchg_relaxed
> #endif
Yeah, small detail: the third one wants to be _release, right?
> Is there any objection to some light CPP usage as above for adding the
> {relaxed,acquire,release} variants?
No objection from me to that way of writing it, this still looks very readable,
and probably more readable than the verbose variants. It's similar in style to
linux/atomic.h which has a good balance of C versus CPP.
What I objected to was the deep nested code generation approach in the original
patch.
CPP is fine in many circumstances, but there's a level of (ab-)use where it
becomes counterproductive.
Thanks,
Ingo
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2017-03-30 12:50 +0200 |
| Message-ID | <tqFOp-55A-9@gated-at.bofh.it> |
| In reply to | #1612606 |
On Thu, Mar 30, 2017 at 08:43:39AM +0200, Ingo Molnar wrote:
>
> * Mark Rutland <mark.rutland@arm.com> wrote:
>
> > With some minimal CPP, it can be a lot more manageable:
> >
> > ----
> > #define INSTR_ATOMIC_XCHG(order) \
> > static __always_inline int atomic_xchg##order(atomic_t *v, int i) \
> > { \
> > kasan_check_write(v, sizeof(*v)); \
> > arch_atomic_xchg##order(v, i); \
> > }
> >
> > #define INSTR_ATOMIC_XCHG()
> >
> > #ifdef arch_atomic_xchg_relaxed
> > INSTR_ATOMIC_XCHG(_relaxed)
> > #define atomic_xchg_relaxed atomic_xchg_relaxed
> > #endif
> >
> > #ifdef arch_atomic_xchg_acquire
> > INSTR_ATOMIC_XCHG(_acquire)
> > #define atomic_xchg_acquire atomic_xchg_acquire
> > #endif
> >
> > #ifdef arch_atomic_xchg_relaxed
> > INSTR_ATOMIC_XCHG(_relaxed)
> > #define atomic_xchg_relaxed atomic_xchg_relaxed
> > #endif
>
> Yeah, small detail: the third one wants to be _release, right?
Yes; my bad.
> > Is there any objection to some light CPP usage as above for adding the
> > {relaxed,acquire,release} variants?
>
> No objection from me to that way of writing it, this still looks very readable,
> and probably more readable than the verbose variants. It's similar in style to
> linux/atomic.h which has a good balance of C versus CPP.
Great. I'll follow the above pattern when adding the ordering variants.
> What I objected to was the deep nested code generation approach in the original
> patch.
>
> CPP is fine in many circumstances, but there's a level of (ab-)use where it
> becomes counterproductive.
Sure, that makes sense to me.
Thanks,
Mark.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web