diff options
author | Peter Zijlstra <peterz@infradead.org> | 2020-08-29 15:03:35 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2020-10-12 18:27:27 +0200 |
commit | 29f006fdefe6f88abde973a0b0f20d2704e93fd4 (patch) | |
tree | 11df0a506bb05fdd72c07a4fed5bbdb80b3b7bf5 /scripts/atomic | |
parent | kprobes: Remove kretprobe hash (diff) | |
download | linux-29f006fdefe6f88abde973a0b0f20d2704e93fd4.tar.xz linux-29f006fdefe6f88abde973a0b0f20d2704e93fd4.zip |
asm-generic/atomic: Add try_cmpxchg() fallbacks
Only x86 provides try_cmpxchg() outside of the atomic_t interfaces,
provide generic fallbacks to create this interface from the widely
available cmpxchg() function.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/159870621515.1229682.15506193091065001742.stgit@devnote2
Diffstat (limited to 'scripts/atomic')
-rwxr-xr-x | scripts/atomic/gen-atomic-fallback.sh | 63 | ||||
-rwxr-xr-x | scripts/atomic/gen-atomic-instrumented.sh | 29 |
2 files changed, 79 insertions, 13 deletions
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh index 693dfa1de430..317a6cec76e1 100755 --- a/scripts/atomic/gen-atomic-fallback.sh +++ b/scripts/atomic/gen-atomic-fallback.sh @@ -144,15 +144,11 @@ gen_proto_order_variants() printf "#endif /* ${basename}_relaxed */\n\n" } -gen_xchg_fallbacks() +gen_order_fallbacks() { local xchg="$1"; shift + cat <<EOF -#ifndef ${xchg}_relaxed -#define ${xchg}_relaxed ${xchg} -#define ${xchg}_acquire ${xchg} -#define ${xchg}_release ${xchg} -#else /* ${xchg}_relaxed */ #ifndef ${xchg}_acquire #define ${xchg}_acquire(...) \\ @@ -169,11 +165,62 @@ cat <<EOF __atomic_op_fence(${xchg}, __VA_ARGS__) #endif -#endif /* ${xchg}_relaxed */ +EOF +} + +gen_xchg_fallbacks() +{ + local xchg="$1"; shift + printf "#ifndef ${xchg}_relaxed\n" + + gen_basic_fallbacks ${xchg} + + printf "#else /* ${xchg}_relaxed */\n" + + gen_order_fallbacks ${xchg} + + printf "#endif /* ${xchg}_relaxed */\n\n" +} + +gen_try_cmpxchg_fallback() +{ + local order="$1"; shift; + +cat <<EOF +#ifndef ${ARCH}try_cmpxchg${order} +#define ${ARCH}try_cmpxchg${order}(_ptr, _oldp, _new) \\ +({ \\ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\ + ___r = ${ARCH}cmpxchg${order}((_ptr), ___o, (_new)); \\ + if (unlikely(___r != ___o)) \\ + *___op = ___r; \\ + likely(___r == ___o); \\ +}) +#endif /* ${ARCH}try_cmpxchg${order} */ EOF } +gen_try_cmpxchg_fallbacks() +{ + printf "#ifndef ${ARCH}try_cmpxchg_relaxed\n" + printf "#ifdef ${ARCH}try_cmpxchg\n" + + gen_basic_fallbacks "${ARCH}try_cmpxchg" + + printf "#endif /* ${ARCH}try_cmpxchg */\n\n" + + for order in "" "_acquire" "_release" "_relaxed"; do + gen_try_cmpxchg_fallback "${order}" + done + + printf "#else /* ${ARCH}try_cmpxchg_relaxed */\n" + + gen_order_fallbacks "${ARCH}try_cmpxchg" + + printf "#endif /* ${ARCH}try_cmpxchg_relaxed */\n\n" +} + cat << EOF // SPDX-License-Identifier: GPL-2.0 @@ -191,6 +238,8 @@ for xchg in "${ARCH}xchg" "${ARCH}cmpxchg" "${ARCH}cmpxchg64"; do gen_xchg_fallbacks "${xchg}" done +gen_try_cmpxchg_fallbacks + grep '^[a-z]' "$1" | while read name meta args; do gen_proto "${meta}" "${name}" "${ARCH}" "atomic" "int" ${args} done diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh index 6afadf73da17..85dc25685c0d 100755 --- a/scripts/atomic/gen-atomic-instrumented.sh +++ b/scripts/atomic/gen-atomic-instrumented.sh @@ -103,14 +103,31 @@ gen_xchg() local xchg="$1"; shift local mult="$1"; shift + if [ "${xchg%${xchg#try_cmpxchg}}" = "try_cmpxchg" ] ; then + +cat <<EOF +#define ${xchg}(ptr, oldp, ...) \\ +({ \\ + typeof(ptr) __ai_ptr = (ptr); \\ + typeof(oldp) __ai_oldp = (oldp); \\ + instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\ + instrument_atomic_write(__ai_oldp, ${mult}sizeof(*__ai_oldp)); \\ + arch_${xchg}(__ai_ptr, __ai_oldp, __VA_ARGS__); \\ +}) +EOF + + else + cat <<EOF -#define ${xchg}(ptr, ...) \\ -({ \\ - typeof(ptr) __ai_ptr = (ptr); \\ - instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\ - arch_${xchg}(__ai_ptr, __VA_ARGS__); \\ +#define ${xchg}(ptr, ...) \\ +({ \\ + typeof(ptr) __ai_ptr = (ptr); \\ + instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\ + arch_${xchg}(__ai_ptr, __VA_ARGS__); \\ }) EOF + + fi } gen_optional_xchg() @@ -160,7 +177,7 @@ grep '^[a-z]' "$1" | while read name meta args; do gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} done -for xchg in "xchg" "cmpxchg" "cmpxchg64"; do +for xchg in "xchg" "cmpxchg" "cmpxchg64" "try_cmpxchg"; do for order in "" "_acquire" "_release" "_relaxed"; do gen_optional_xchg "${xchg}" "${order}" done |