944bc9cca7
Use __always_inline for atomic fallback wrappers. When building for size (CC_OPTIMIZE_FOR_SIZE), some compilers appear to be less inclined to inline even relatively small static inline functions that are assumed to be inlinable such as atomic ops. This can cause problems, for example in UACCESS regions. While the fallback wrappers aren't pure wrappers, they are trivial nonetheless, and the function they wrap should determine the final inlining policy. For x86 tinyconfig we observe: - vmlinux baseline: 1315988 - vmlinux with patch: 1315928 (-60 bytes) Suggested-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Marco Elver <elver@google.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
184 lines
4.6 KiB
Bash
Executable File
184 lines
4.6 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
ATOMICDIR=$(dirname $0)
|
|
|
|
. ${ATOMICDIR}/atomic-tbl.sh
|
|
|
|
#gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...)
|
|
gen_template_fallback()
|
|
{
|
|
local template="$1"; shift
|
|
local meta="$1"; shift
|
|
local pfx="$1"; shift
|
|
local name="$1"; shift
|
|
local sfx="$1"; shift
|
|
local order="$1"; shift
|
|
local atomic="$1"; shift
|
|
local int="$1"; shift
|
|
|
|
local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
|
|
|
|
local ret="$(gen_ret_type "${meta}" "${int}")"
|
|
local retstmt="$(gen_ret_stmt "${meta}")"
|
|
local params="$(gen_params "${int}" "${atomic}" "$@")"
|
|
local args="$(gen_args "$@")"
|
|
|
|
if [ ! -z "${template}" ]; then
|
|
printf "#ifndef ${atomicname}\n"
|
|
. ${template}
|
|
printf "#define ${atomicname} ${atomicname}\n"
|
|
printf "#endif\n\n"
|
|
fi
|
|
}
|
|
|
|
#gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
|
|
gen_proto_fallback()
|
|
{
|
|
local meta="$1"; shift
|
|
local pfx="$1"; shift
|
|
local name="$1"; shift
|
|
local sfx="$1"; shift
|
|
local order="$1"; shift
|
|
|
|
local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
|
|
gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@"
|
|
}
|
|
|
|
#gen_basic_fallbacks(basename)
|
|
gen_basic_fallbacks()
|
|
{
|
|
local basename="$1"; shift
|
|
cat << EOF
|
|
#define ${basename}_acquire ${basename}
|
|
#define ${basename}_release ${basename}
|
|
#define ${basename}_relaxed ${basename}
|
|
EOF
|
|
}
|
|
|
|
#gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...)
|
|
gen_proto_order_variants()
|
|
{
|
|
local meta="$1"; shift
|
|
local pfx="$1"; shift
|
|
local name="$1"; shift
|
|
local sfx="$1"; shift
|
|
local atomic="$1"
|
|
|
|
local basename="${atomic}_${pfx}${name}${sfx}"
|
|
|
|
local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
|
|
|
|
# If we don't have relaxed atomics, then we don't bother with ordering fallbacks
|
|
# read_acquire and set_release need to be templated, though
|
|
if ! meta_has_relaxed "${meta}"; then
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
|
|
|
|
if meta_has_acquire "${meta}"; then
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
|
|
fi
|
|
|
|
if meta_has_release "${meta}"; then
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
|
|
fi
|
|
|
|
return
|
|
fi
|
|
|
|
printf "#ifndef ${basename}_relaxed\n"
|
|
|
|
if [ ! -z "${template}" ]; then
|
|
printf "#ifdef ${basename}\n"
|
|
fi
|
|
|
|
gen_basic_fallbacks "${basename}"
|
|
|
|
if [ ! -z "${template}" ]; then
|
|
printf "#endif /* ${atomic}_${pfx}${name}${sfx} */\n\n"
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
|
|
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@"
|
|
fi
|
|
|
|
printf "#else /* ${basename}_relaxed */\n\n"
|
|
|
|
gen_template_fallback "${ATOMICDIR}/fallbacks/acquire" "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
|
|
gen_template_fallback "${ATOMICDIR}/fallbacks/release" "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
|
|
gen_template_fallback "${ATOMICDIR}/fallbacks/fence" "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
|
|
|
|
printf "#endif /* ${basename}_relaxed */\n\n"
|
|
}
|
|
|
|
gen_xchg_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(...) \\
|
|
__atomic_op_acquire(${xchg}, __VA_ARGS__)
|
|
#endif
|
|
|
|
#ifndef ${xchg}_release
|
|
#define ${xchg}_release(...) \\
|
|
__atomic_op_release(${xchg}, __VA_ARGS__)
|
|
#endif
|
|
|
|
#ifndef ${xchg}
|
|
#define ${xchg}(...) \\
|
|
__atomic_op_fence(${xchg}, __VA_ARGS__)
|
|
#endif
|
|
|
|
#endif /* ${xchg}_relaxed */
|
|
|
|
EOF
|
|
}
|
|
|
|
cat << EOF
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
// Generated by $0
|
|
// DO NOT MODIFY THIS FILE DIRECTLY
|
|
|
|
#ifndef _LINUX_ATOMIC_FALLBACK_H
|
|
#define _LINUX_ATOMIC_FALLBACK_H
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
EOF
|
|
|
|
for xchg in "xchg" "cmpxchg" "cmpxchg64"; do
|
|
gen_xchg_fallbacks "${xchg}"
|
|
done
|
|
|
|
grep '^[a-z]' "$1" | while read name meta args; do
|
|
gen_proto "${meta}" "${name}" "atomic" "int" ${args}
|
|
done
|
|
|
|
cat <<EOF
|
|
#define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
|
|
#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
|
|
|
|
#ifdef CONFIG_GENERIC_ATOMIC64
|
|
#include <asm-generic/atomic64.h>
|
|
#endif
|
|
|
|
EOF
|
|
|
|
grep '^[a-z]' "$1" | while read name meta args; do
|
|
gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
|
|
done
|
|
|
|
cat <<EOF
|
|
#define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
|
|
#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
|
|
|
|
#endif /* _LINUX_ATOMIC_FALLBACK_H */
|
|
EOF
|